home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / xanim / xanim_qt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-23  |  119.7 KB  |  3,830 lines

  1.  
  2. /*
  3.  * xanim_qt.c
  4.  *
  5.  * Copyright (C) 1993,1994 by Mark Podlipec.
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  *
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim_qt.h"
  19.  
  20. ULONG QT_Decode_RLE();
  21. ULONG QT_Decode_RLE16();
  22. ULONG QT_Decode_RLE24();
  23. ULONG QT_Decode_RLE33();
  24. ULONG QT_Decode_RAW();
  25. ULONG QT_Decode_RPZA();
  26. ULONG QT_Decode_SMC();
  27. ULONG QT_Decode_CVID();
  28. ULONG QT_Decode_YUV2();
  29. ULONG QT_Decode_SPIG();
  30. ULONG QT_Read_Video_Codec_HDR();
  31. ULONG QT_Read_Audio_Codec_HDR();
  32. void QT_Audio_Type();
  33. ULONG QT_Read_File();
  34. void QT_Gen_YUV_Tabs();
  35. void QT_CVID_C1();
  36. void QT_CVID_C4();
  37. void QT_Create_Default_Cmap();
  38. char *XA_rindex();
  39.  
  40. ULONG qt_cmap_cnt,qt_cmap_flag;
  41. void CMAP_Cache_Clear();
  42. void CMAP_Cache_Init();
  43.  
  44. #define SMC_MAX_CNT 256
  45. static ULONG smc_8cnt,smc_Acnt,smc_Ccnt;
  46. static ULONG smc_8[ (2 * SMC_MAX_CNT) ];
  47. static ULONG smc_A[ (4 * SMC_MAX_CNT) ];
  48. static ULONG smc_C[ (8 * SMC_MAX_CNT) ];
  49.  
  50. QTV_CODEC_HDR *qtv_codecs;
  51. QTS_CODEC_HDR *qts_codecs;
  52. ULONG qtv_codec_num,qts_codec_num;
  53.  
  54. XA_ACTION *ACT_Get_Action();
  55. XA_CHDR *ACT_Get_CMAP();
  56. XA_CHDR *CMAP_Create_332();
  57. XA_CHDR *CMAP_Create_422();
  58. XA_CHDR *CMAP_Create_Gray();
  59. void ACT_Add_CHDR_To_Action();
  60. void ACT_Setup_Mapped();
  61. XA_CHDR *CMAP_Create_CHDR_From_True();
  62. UBYTE *UTIL_RGB_To_FS_Map();
  63. UBYTE *UTIL_RGB_To_Map();
  64. ULONG CMAP_Find_Closest();
  65.  
  66. ULONG UTIL_Get_MSB_Long();
  67. LONG UTIL_Get_MSB_Short();
  68. ULONG UTIL_Get_MSB_UShort();
  69.  
  70. FILE *QT_Open_File();
  71. void  QT_Parse_Chunks();
  72. ULONG QT_Parse_Bin();
  73. void  QT_Read_Video_Data();
  74. void  QT_Read_Audio_Data();
  75.  
  76. void yuv_to_rgb();
  77. void QT_Print_ID();
  78. void QT_Read_MVHD();
  79. void QT_Read_TKHD();
  80. void QT_Read_ELST();
  81. void QT_Read_MDHD();
  82. void QT_Read_HDLR();
  83. void QT_Read_Video_STSD();
  84. void QT_Read_Audio_STSD();
  85. void QT_Read_Name();
  86. void QT_Read_STTS();
  87. void QT_Read_STSS();
  88. void QT_Read_STCO();
  89. void QT_Read_STSZ();
  90. void QT_Read_STSC();
  91. void QT_Read_STGS();
  92. void QT_Codec_List();
  93. ULONG QT_Get_Color();
  94. void QT_Get_RGBColor();
  95. void QT_Get_AV_Colors();
  96. void QT_Get_AV_RGBColors();
  97. ULONG QT_Get_Color24();
  98.  
  99.  
  100. QT_MVHDR qt_mvhdr;
  101. QT_TKHDR qt_tkhdr;
  102. QT_MDHDR qt_mdhdr;
  103. QT_HDLR_HDR qt_hdlr_hdr;
  104.  
  105. char qt_rfilename[256];
  106. char qt_dfilename[256];
  107. ULONG qt_video_flag;
  108. ULONG qt_data_flag;
  109. ULONG qt_v_flag,qt_s_flag;
  110.  
  111.  
  112. #define QT_MAX_COLORS  256
  113. ColorReg qt_cmap[QT_MAX_COLORS];
  114. XA_CHDR *qt_chdr;
  115. USHORT qt_gamma_adj[32];
  116.  
  117. ULONG qt_frame_cnt;
  118. ULONG qt_imagex,qt_imagey,qt_imagec;
  119. ULONG qt_max_imagex,qt_max_imagey;
  120. ULONG qt_compression,qt_depth;
  121. ULONG qt_max_fsize;
  122. ULONG qt_time,qt_timelo;
  123. ULONG qt_timescale,qt_mv_timescale,qt_tk_timescale,qt_md_timescale;
  124.  
  125. #define QT_CODEC_UNK   0x000
  126. #define QT_CODEC_RLE   0x001
  127. #define QT_CODEC_RLE16 0x002
  128. #define QT_CODEC_RLE24 0x003
  129. #define QT_CODEC_RLE33 0x004
  130. #define QT_CODEC_RAW   0x008
  131. #define QT_CODEC_SMC   0x010
  132. #define QT_CODEC_RPZA  0x020
  133. #define QT_CODEC_CVID  0x030
  134. #define QT_CODEC_YUV2  0x040
  135. #define QT_CODEC_SPIG  0x050
  136.  
  137. /* YUV cache tables for CVID */
  138. static LONG *QT_UB_tab=0;
  139. static LONG *QT_VR_tab=0;
  140. static LONG *QT_UG_tab=0;
  141. static LONG *QT_VG_tab=0;
  142.  
  143. /*** SOUND SUPPORT ****/
  144. ULONG qt_audio_attempt;
  145. ULONG qt_audio_type;
  146. ULONG qt_audio_freq;
  147. ULONG qt_audio_chans;
  148. ULONG qt_audio_bps;
  149. ULONG qt_audio_end;
  150. #ifdef POD_AUDIO_BETA
  151. void XA_Add_Sound();
  152. #endif
  153.  
  154.  
  155.  
  156. QT_FRAME *qt_frame_start,*qt_frame_cur;
  157.  
  158. QT_FRAME *QT_Add_Frame(time,timelo,act)
  159. ULONG time,timelo;
  160. XA_ACTION *act;
  161. {
  162.   QT_FRAME *fframe;
  163.  
  164.   fframe = (QT_FRAME *) malloc(sizeof(QT_FRAME));
  165.   if (fframe == 0) TheEnd1("QT_Add_Frame: malloc err");
  166.  
  167.   fframe->time = time;
  168.   fframe->timelo = timelo;
  169.   fframe->act = act;
  170.   fframe->next = 0;
  171.  
  172.   if (qt_frame_start == 0) qt_frame_start = fframe;
  173.   else qt_frame_cur->next = fframe;
  174.  
  175.   qt_frame_cur = fframe;
  176.   qt_frame_cnt++;
  177.   return(fframe);
  178. }
  179.  
  180. void QT_Free_Frame_List(fframes)
  181. QT_FRAME *fframes;
  182. {
  183.   QT_FRAME *ftmp;
  184.   while(fframes != 0)
  185.   {
  186.     ftmp = fframes;
  187.     fframes = fframes->next;
  188.     FREE(ftmp,0x9000);
  189.   }
  190. }
  191.  
  192.  
  193. LONG Is_QT_File(filename)
  194. char *filename;
  195. {
  196.   FILE *fin;
  197.   ULONG ret;
  198.  
  199.   if ( (fin=QT_Open_File(filename,qt_rfilename,qt_dfilename)) == 0)
  200.                 return(XA_NOFILE);
  201.   ret = QT_Parse_Bin(fin);
  202.   fclose(fin);
  203.   if ( ret != 0 ) return(TRUE);
  204.   return(FALSE);
  205. }
  206.  
  207. /* FOR PARSING Quicktime Files */
  208. ULONG *qtv_samp_sizes,*qts_samp_sizes;
  209. ULONG qtv_samp_num,qts_samp_num;
  210. ULONG qts_init_duration;
  211.  
  212. QT_S2CHUNK_HDR *qtv_s2chunks,*qts_s2chunks;
  213. ULONG qtv_s2chunk_num,qts_s2chunk_num;
  214.  
  215. QT_T2SAMP_HDR *qtv_t2samps,*qts_t2samps;
  216. ULONG qtv_t2samp_num,qts_t2samp_num;
  217.  
  218. ULONG qtv_chunkoff_num,qts_chunkoff_num;
  219. ULONG *qtv_chunkoffs,*qts_chunkoffs;
  220. UBYTE *qt_pic;
  221. ULONG qt_pic_size;
  222.  
  223. ULONG qtv_codec_lstnum,qts_codec_lstnum;
  224. ULONG qtv_chunkoff_lstnum,qts_chunkoff_lstnum;
  225. ULONG qtv_samp_lstnum,qts_samp_lstnum;
  226. ULONG qtv_s2chunk_lstnum,qts_s2chunk_lstnum;
  227. ULONG qt_stgs_num;
  228.  
  229. /* main() */
  230. ULONG QT_Read_File(fname,anim_hdr)
  231. char *fname;
  232. XA_ANIM_HDR *anim_hdr;
  233. {
  234.   FILE *fin;
  235.   LONG i;
  236.  
  237.   qt_stgs_num = 0;
  238.   qt_cmap_flag = 0;
  239.   qt_cmap_cnt = 0;
  240.   qtv_codec_lstnum    = qts_codec_lstnum = 0;
  241.   qtv_chunkoff_lstnum    = qts_chunkoff_lstnum = 0;
  242.   qtv_samp_lstnum    = qts_samp_lstnum = 0;
  243.   qtv_codecs = 0;
  244.   qts_codecs = 0;
  245.   qtv_codec_num     = qts_codec_num = 0;
  246.   qt_data_flag = FALSE;
  247.   qt_video_flag        = 0;
  248.   qt_v_flag        = qt_s_flag = 0;
  249.   qt_compression    = QT_CODEC_UNK;
  250.   qt_depth = 0;
  251.   qt_pic = 0;
  252.   qt_pic_size = 0;
  253.  
  254.   qt_chdr = 0;
  255.   qt_frame_cnt = 0;
  256.   qt_frame_start = 0;
  257.   qt_frame_cur = 0;
  258.   qt_time = XA_GET_TIME( 100 ); /* default 10 frames per second */
  259.   qt_timelo = 0;
  260.   qt_timescale        = 1000;
  261.   qt_mv_timescale = qt_tk_timescale = qt_md_timescale = 1000;
  262.   qtv_chunkoff_num    = qts_chunkoff_num = 0;
  263.   qtv_chunkoffs        = qts_chunkoffs = 0;
  264.   qtv_s2chunk_num    = qts_s2chunk_lstnum = 0;
  265.   qtv_s2chunks        = qts_s2chunks = 0;
  266.   qtv_s2chunk_num    = qts_s2chunk_lstnum = 0;
  267.   qtv_t2samp_num    = qts_t2samp_num = 0;
  268.   qtv_t2samps        = qts_t2samps = 0;
  269.   qtv_samp_sizes    = qts_samp_sizes = 0;
  270.   qtv_samp_num        = qts_samp_num = 0;
  271.   qts_init_duration    = 0;
  272.   qt_imagex = qt_imagey = qt_imagec = 0;
  273.   qt_max_fsize = 0;
  274.   qt_max_imagex = qt_max_imagey = 0;
  275.  
  276.   qt_audio_attempt = FALSE;
  277.  
  278.   for(i=0;i<32;i++) qt_gamma_adj[i] = xa_gamma_adj[ ((i<<3)|(i>>2)) ];
  279.  
  280.   if ( (fin=QT_Open_File(fname,qt_rfilename,qt_dfilename)) == 0)
  281.   {
  282.     fprintf(stderr,"QT_Read: can't open %s\n",qt_rfilename);
  283.     return(FALSE);
  284.   }
  285.  
  286.   if ( QT_Parse_Bin(fin) == 0 )
  287.   {
  288.     fprintf(stderr,"Not quicktime file\n");
  289.     return(FALSE);
  290.   }
  291.  
  292. DEBUG_LEVEL1 fprintf(stderr,"parsing chunks\n");
  293.   QT_Parse_Chunks(fin);
  294.  
  295.   if (qt_data_flag == FALSE) 
  296.   { /* mdat was not in .rscr file need to open .data file */
  297.     fclose(fin); /* close .rscr file */
  298.     if (qt_dfilename[0] == 0)
  299.     {
  300.        fprintf(stderr,"QT_Data: No data in %s file. Can't find .data file.\n",
  301.         qt_rfilename);
  302.        return(FALSE);
  303.     }
  304.     if ( (fin=fopen(qt_dfilename,XA_OPEN_MODE)) == 0) 
  305.     {
  306.       fprintf(stderr,"QT_Data: can't open %s file.\n",qt_dfilename);
  307.       return(FALSE);
  308.     }
  309.   } else strcpy(qt_dfilename,qt_rfilename); /* r file is d file */
  310. DEBUG_LEVEL1 fprintf(stderr,"reading data\n");
  311.   QT_Read_Video_Data(fin,anim_hdr);
  312.   QT_Read_Audio_Data(fin,anim_hdr);
  313.   fclose(fin);
  314.  
  315.   if (xa_verbose) fprintf(stderr,"    Frames %ld\n", qt_frame_cnt);
  316.  
  317.   anim_hdr->frame_lst = (XA_FRAME *)
  318.                                 malloc( sizeof(XA_FRAME) * (qt_frame_cnt+1));
  319.   if (anim_hdr->frame_lst == NULL) TheEnd1("QT_Read_File: frame malloc err");
  320.  
  321.   qt_frame_cur = qt_frame_start;
  322.   i = 0;
  323.   while(qt_frame_cur != 0)
  324.   {
  325.     if (i >= qt_frame_cnt)
  326.     {
  327.       fprintf(stderr,"QT_Read_Anim: frame inconsistency %ld %ld\n",
  328.                 i,qt_frame_cnt);
  329.       break;
  330.     }
  331.     anim_hdr->frame_lst[i].time = qt_frame_cur->time;
  332.     anim_hdr->frame_lst[i].timelo = qt_frame_cur->timelo;
  333.     anim_hdr->frame_lst[i].act = qt_frame_cur->act;
  334.     qt_frame_cur = qt_frame_cur->next;
  335.     i++;
  336.   }
  337.   anim_hdr->imagex = qt_max_imagex;
  338.   anim_hdr->imagey = qt_max_imagey;
  339.   anim_hdr->imagec = qt_imagec;
  340.   anim_hdr->imaged = 8; /* nop */
  341.   anim_hdr->frame_lst[i].time = 0;
  342.   anim_hdr->frame_lst[i].timelo = 0;
  343.   anim_hdr->frame_lst[i].act  = 0;
  344.   anim_hdr->loop_frame = 0;
  345.   if (xa_buffer_flag == FALSE) anim_hdr->anim_flags |= ANIM_SNG_BUF;
  346.   anim_hdr->max_fsize = qt_max_fsize;
  347.   if (xa_file_flag == TRUE) 
  348.   {
  349.     ULONG len;
  350.     anim_hdr->anim_flags |= ANIM_USE_FILE;
  351.     len = strlen(qt_dfilename) + 1;
  352.     anim_hdr->fname = (char *)malloc(len);
  353.     if (anim_hdr->fname==0) TheEnd1("QT: malloc fname err");
  354.     strcpy(anim_hdr->fname,qt_dfilename);
  355.   }
  356.   if (i > 0) anim_hdr->last_frame = i - 1;
  357.   else i = 0;
  358.   QT_Free_Frame_List(qt_frame_start);
  359.   if (qtv_samp_sizes) free(qtv_samp_sizes);
  360.   if (qts_samp_sizes) free(qts_samp_sizes);
  361.   if (qtv_codecs) free(qtv_codecs);
  362.   if (qts_codecs) free(qts_codecs);
  363.   if (qtv_t2samps) free(qtv_t2samps);
  364.   if (qts_t2samps) free(qts_t2samps);
  365.   if (qtv_s2chunks) free(qtv_s2chunks);
  366.   if (qts_s2chunks) free(qts_s2chunks);
  367.   if (qtv_chunkoffs) free(qtv_chunkoffs);
  368.   if (qts_chunkoffs) free(qts_chunkoffs);
  369.   return(TRUE);
  370. }
  371.  
  372. FILE *QT_Open_File(fname,r_file,d_file)
  373. char *fname,*r_file,*d_file;
  374. {
  375.   FILE *fin;
  376.  
  377.   /* check to see if fname exists? */
  378.   if ( (fin=fopen(fname,XA_OPEN_MODE)) != 0)  /* filename is as give */
  379.   { /*three choices - with or without .rsrc ending, or using .resource subdir*/
  380.     LONG len;
  381.     FILE *ftst;
  382.     /* path/fname exits. */
  383.  
  384.     /* check for  path/.resource/fname */
  385.     {
  386.       char *lastdirsep;
  387.       strcpy(r_file,fname);            /* copy path/fname to r */
  388.       lastdirsep = XA_rindex(r_file, '/');    /* find sep if any */
  389.       if ( lastdirsep != (char *)(NULL) )
  390.       {
  391.         strcpy(d_file,lastdirsep);        /* save fname to d*/
  392.     lastdirsep++; *lastdirsep = 0;        /* cut of fname off r*/
  393.         strcat(lastdirsep, ".resource/");     /* add .resource to r*/
  394.         strcat(r_file, d_file);         /* add fname to r */
  395.       }
  396.       else /* no path */
  397.       {
  398.     strcpy(r_file,".resource/");
  399.     strcat(r_file,fname);
  400.       }
  401.       if ( (ftst=fopen(r_file,"r")) != 0)
  402.       {
  403.     /* path/fname and path/.resource/fname exist - wrap it up */
  404.     strcpy(d_file,fname);            /* setup .data name */
  405.     fclose(fin);                /* close .data fork */
  406.         return(ftst);        /* return .rsrc fork (in .resource) */
  407.       }
  408.     }
  409.      
  410.     /* Now check for .rsrc or .data endings */
  411.     strcpy(r_file,fname);
  412.     strcpy(d_file,fname);
  413.     len = strlen(r_file) - 5;
  414.     if (len > 0)
  415.     { char *tmp;
  416.       tmp = XA_rindex(d_file, '.');    /* get last "." */
  417.       if ( tmp == (char *)(NULL) ) { *d_file = 0; return(fin); }
  418.       else if (strcmp(tmp,".rsrc")==0)  /* fname has .rsrc ending */
  419.       {
  420.         strcpy(tmp,".data"); /* overwrite .rsrc with .data in d*/
  421.     return(fin);
  422.       }
  423.       else if (strcmp(tmp,".data")==0)  /* fname has .data ending */
  424.       {
  425.         strcpy(tmp,".rsrc"); /* overwrite .rsrc with .data in d*/
  426.         if ( (ftst=fopen(d_file,"r")) != 0) /* see if .rsrc exists */
  427.     {
  428.       char t_file[256];  /* swap r and d files */
  429.       strcpy(t_file,r_file); strcpy(r_file,d_file); strcpy(d_file,t_file);
  430.       fclose(fin);        /* close .data file */
  431.       return(ftst);        /* return .rsrc file */
  432.     }
  433.     /* hopefully .data is flattened. find out later */
  434.     else { *d_file = 0; return(fin); }
  435.       }
  436.       else { *d_file = 0; return(fin); }
  437.     }
  438.     else { *d_file = 0; return(fin); }
  439.   }
  440.  
  441.   /* does fname.rsrc exist? */
  442.   strcpy(r_file,fname);
  443.   strcat(r_file,".rsrc");
  444.   if ( (fin=fopen(r_file,XA_OPEN_MODE)) != 0)  /* fname.rsrc */
  445.   { FILE *ftst;
  446.     /* if so, check .data existence */
  447.     strcpy(d_file,fname);
  448.     strcat(d_file,".data");
  449.     if ( (ftst=fopen(d_file,XA_OPEN_MODE)) != 0)    fclose(ftst);
  450.     else *d_file = 0;
  451.     return(fin);
  452.   } else *d_file = 0;
  453.   return(0);
  454. }
  455.  
  456. void QT_Parse_Chunks(fin)
  457. FILE *fin;
  458. {
  459.   LONG file_len;
  460.   ULONG id,len;
  461.  
  462.   file_len = 1;
  463.   while(file_len > 0)
  464.   {
  465.     len = UTIL_Get_MSB_Long(fin);
  466.     id  = UTIL_Get_MSB_Long(fin);
  467.  
  468.     if ( (len == 0) && (id == QT_mdat) )
  469.     TheEnd1("QT: mdat len is 0. You also need a .rsrc file.\n");
  470.     if (len < 8) { file_len = 0; continue; } /* just bad - finish this */
  471.     if (file_len == 1)
  472.     {
  473.       if (id == QT_moov) file_len = len;
  474.       else file_len = len + 1;
  475.     }
  476.     DEBUG_LEVEL2 fprintf(stderr,"%c%c%c%c %04lx len = %lx file_len =  %lx\n",
  477.     (id >> 24),((id>>16)&0xff),((id>>8)&0xff),(id&0xff),id,len,file_len);
  478.  
  479.     switch(id)
  480.     {
  481.     /*--------------ATOMS------------------*/
  482.       case QT_trak:
  483.     qt_v_flag = qt_s_flag = 0;
  484.     qtv_codec_lstnum = qtv_codec_num;
  485.     qts_codec_lstnum = qts_codec_num;
  486.     qtv_chunkoff_lstnum = qtv_chunkoff_num;
  487.     qts_chunkoff_lstnum = qts_chunkoff_num;
  488.     qtv_samp_lstnum = qtv_samp_num;
  489.     qts_samp_lstnum = qts_samp_num;
  490.     qtv_s2chunk_lstnum = qtv_s2chunk_num;
  491.     qts_s2chunk_lstnum = qts_s2chunk_num;
  492.       case QT_moov:
  493.       case QT_mdia:
  494.       case QT_minf:
  495.       case QT_stbl:
  496.       case QT_edts:
  497.     file_len -= 8;
  498.     break;
  499.     /*---------------STUFF------------------*/
  500.       case QT_mvhd:
  501.     QT_Read_MVHD(fin,&qt_mvhdr);
  502.     file_len -= len;
  503.     break;
  504.       case QT_tkhd:
  505.     QT_Read_TKHD(fin,&qt_tkhdr);
  506.     file_len -= len;
  507.     break;
  508.       case QT_elst:
  509.     QT_Read_ELST(fin);
  510.     file_len -= len;
  511.     break;
  512.       case QT_mdhd:
  513.     QT_Read_MDHD(fin,&qt_mdhdr);
  514.     file_len -= len;
  515.     break;
  516.       case QT_hdlr:
  517.     QT_Read_HDLR(fin,len,&qt_hdlr_hdr);
  518.     file_len -= len;
  519.     break;
  520.     /*--------------DATA CHUNKS-------------*/
  521.       case QT_mdat:  /* data is included in .rsrc - assumed flatness */
  522.     fseek(fin,(len-8),1); /* skip over it for now */
  523.     qt_data_flag = TRUE;
  524.     break;
  525.       case QT_stsd:
  526.     qt_video_flag = 0;
  527.     if (qt_v_flag) QT_Read_Video_STSD(fin);
  528.     else if (qt_s_flag) QT_Read_Audio_STSD(fin);
  529.         else fseek(fin,(len-8),1);
  530.     file_len -= len;
  531.     break;
  532.       case QT_stts:
  533.     if (qt_v_flag) 
  534.         QT_Read_STTS(fin,(len-8),&qtv_t2samp_num,&qtv_t2samps);
  535. /*POD NOTE: AUDIO don't need? probably, just haven't been bit by it yet.
  536.     else if (qt_s_flag) 
  537.         QT_Read_STTS(fin,(len-8),&qts_t2samp_num,&qts_t2samps);
  538. */
  539.         else    fseek(fin,(len-8),1);
  540.     file_len -= len;
  541.     break;
  542.       case QT_stss:
  543.     QT_Read_STSS(fin);
  544.     file_len -= len;
  545.     break;
  546.       case QT_stco:
  547.     if (qt_v_flag) QT_Read_STCO(fin,&qtv_chunkoff_num,&qtv_chunkoffs);
  548.     else if (qt_s_flag) QT_Read_STCO(fin,&qts_chunkoff_num,&qts_chunkoffs);
  549.     else fseek(fin,(len-8),1);
  550.     file_len -= len;
  551.     break;
  552.       case QT_stsz:
  553.     if (qt_v_flag) QT_Read_STSZ(fin,len,&qtv_samp_num,&qtv_samp_sizes);
  554.     else if (qt_s_flag) 
  555.         QT_Read_STSZ(fin,len,&qts_samp_num,&qts_samp_sizes);
  556.     else fseek(fin,(len-8),1);
  557.     file_len -= len;
  558.     break;
  559.       case QT_stsc:
  560.     if (qt_v_flag) QT_Read_STSC(fin,len,&qtv_s2chunk_num,&qtv_s2chunks,
  561.             qtv_chunkoff_lstnum,qtv_codec_num,qtv_codec_lstnum);
  562.     else if (qt_s_flag) QT_Read_STSC(fin,len,&qts_s2chunk_num,&qts_s2chunks,
  563.             qts_chunkoff_lstnum,qts_codec_num,qts_codec_lstnum);
  564.     else fseek(fin,(len-8),1);
  565.     file_len -= len;
  566.     break;
  567.       case QT_stgs:
  568.     QT_Read_STGS(fin,len);
  569.     file_len -= len;
  570.     break;
  571.     /*-----------Sound Codec Headers--------------*/
  572.       case QT_raw00:
  573.     /*-----------Video/Sound Codec Headers--------------*/
  574.       case QT_raw:
  575.     /*-----------Video Codec Headers--------------*/
  576.       case QT_smc:
  577.       case QT_rpza:
  578.       case QT_rle:
  579.       case QT_cvid:
  580.     fprintf(stderr,"QT: Warning %08lx\n",id);
  581.         fseek(fin,(len-8),1);  /* skip over */
  582.     file_len -= len;
  583.     break;
  584.     /*-----------TYPE OF TRAK---------------*/
  585.       case QT_vmhd:
  586.         fseek(fin,(len-8),1);
  587.     file_len -= len; qt_v_flag = 1;
  588.     qt_timescale = qt_md_timescale;
  589.     break;
  590.       case QT_smhd:
  591.         fseek(fin,(len-8),1);
  592.     file_len -= len; qt_s_flag = 1;
  593.     break;
  594.     /*--------------IGNORED FOR NOW---------*/
  595.       case QT_gmhd:
  596.       case QT_text:
  597.       case QT_skip:
  598.       case QT_udta:
  599.       case QT_dinf:
  600.         fseek(fin,(len-8),1);  /* skip over */
  601.     file_len -= len;
  602.     break;
  603.     /*--------------UNKNOWN-----------------*/
  604.       default:
  605.     if ( !feof(fin) && (len <= file_len) )
  606.     {
  607.       LONG i;
  608.       QT_Print_ID(stderr,id,1);
  609.       fprintf(stderr," len = %lx\n",len);
  610.       i = (LONG)(len) - 8;
  611.       while(i > 0) { i--; getc(fin); if (feof(fin)) i = 0; }
  612.     }
  613.     file_len -= len;
  614.     break;
  615.     } /* end of switch */
  616.     if ( feof(fin) ) file_len = 0;
  617.   } /* end of while */
  618. }
  619.  
  620. void QT_Print_ID(fout,id,flag)
  621. FILE *fout;
  622. LONG id,flag;
  623. {
  624.  fprintf(fout,"%c",     ((id >> 24) & 0xff));
  625.  fprintf(fout,"%c",     ((id >> 16) & 0xff));
  626.  fprintf(fout,"%c",     ((id >>  8) & 0xff));
  627.  fprintf(fout,"%c",      (id        & 0xff));
  628.  if (flag) fprintf(fout,"(%lx)",id);
  629. }
  630.  
  631.  
  632. void QT_Read_MVHD(fin,qt_mvhdr)
  633. FILE *fin;
  634. QT_MVHDR *qt_mvhdr;
  635. {
  636.   ULONG i,j;
  637.  
  638.   qt_mvhdr->version =    UTIL_Get_MSB_Long(fin);
  639.   qt_mvhdr->creation =    UTIL_Get_MSB_Long(fin);
  640.   qt_mvhdr->modtime =    UTIL_Get_MSB_Long(fin);
  641.   qt_mvhdr->timescale =    UTIL_Get_MSB_Long(fin);
  642.   qt_mvhdr->duration =    UTIL_Get_MSB_Long(fin);
  643.   qt_mvhdr->rate =    UTIL_Get_MSB_Long(fin);
  644.   qt_mvhdr->volume =    UTIL_Get_MSB_UShort(fin);
  645.   qt_mvhdr->r1  =    UTIL_Get_MSB_Long(fin);
  646.   qt_mvhdr->r2  =    UTIL_Get_MSB_Long(fin);
  647.   for(i=0;i<3;i++) for(j=0;j<3;j++) 
  648.     qt_mvhdr->matrix[i][j]=UTIL_Get_MSB_Long(fin);
  649.   qt_mvhdr->r3  =    UTIL_Get_MSB_UShort(fin);
  650.   qt_mvhdr->r4  =    UTIL_Get_MSB_Long(fin);
  651.   qt_mvhdr->pv_time =    UTIL_Get_MSB_Long(fin);
  652.   qt_mvhdr->post_time =    UTIL_Get_MSB_Long(fin);
  653.   qt_mvhdr->sel_time =    UTIL_Get_MSB_Long(fin);
  654.   qt_mvhdr->sel_durat =    UTIL_Get_MSB_Long(fin);
  655.   qt_mvhdr->cur_time =    UTIL_Get_MSB_Long(fin);
  656.   qt_mvhdr->nxt_tk_id =    UTIL_Get_MSB_Long(fin);
  657.  
  658.   if (qt_mvhdr->timescale) qt_mv_timescale = qt_mvhdr->timescale;
  659.   else qt_mv_timescale = 1000;
  660.   qt_timescale = qt_mv_timescale;
  661.   
  662.   DEBUG_LEVEL2
  663.   {
  664.     fprintf(stderr,"mv   ver = %lx  timescale = %lx  duration = %lx\n",
  665.     qt_mvhdr->version,qt_mvhdr->timescale, qt_mvhdr->duration);
  666.     fprintf(stderr,"     rate = %lx volumne = %lx  nxt_tk = %lx\n",
  667.     qt_mvhdr->rate,qt_mvhdr->volume,qt_mvhdr->nxt_tk_id);
  668.   }
  669. }
  670.  
  671. void QT_Read_TKHD(fin,qt_tkhdr)
  672. FILE *fin;
  673. QT_TKHDR *qt_tkhdr;
  674. {
  675.   ULONG i,j;
  676.  
  677.   qt_tkhdr->version =    UTIL_Get_MSB_Long(fin);
  678.   qt_tkhdr->creation =    UTIL_Get_MSB_Long(fin);
  679.   qt_tkhdr->modtime =    UTIL_Get_MSB_Long(fin);
  680.   qt_tkhdr->trackid =    UTIL_Get_MSB_Long(fin);
  681.   qt_tkhdr->timescale =    UTIL_Get_MSB_Long(fin);
  682.   qt_tkhdr->duration =    UTIL_Get_MSB_Long(fin);
  683.   qt_tkhdr->time_off =    UTIL_Get_MSB_Long(fin);
  684.   qt_tkhdr->priority  =    UTIL_Get_MSB_Long(fin);
  685.   qt_tkhdr->layer  =    UTIL_Get_MSB_UShort(fin);
  686.   qt_tkhdr->alt_group = UTIL_Get_MSB_UShort(fin);
  687.   qt_tkhdr->volume  =    UTIL_Get_MSB_UShort(fin);
  688.   for(i=0;i<3;i++) for(j=0;j<3;j++) 
  689.             qt_tkhdr->matrix[i][j]=UTIL_Get_MSB_Long(fin);
  690.   qt_tkhdr->tk_width =    UTIL_Get_MSB_Long(fin);
  691.   qt_tkhdr->tk_height =    UTIL_Get_MSB_Long(fin);
  692.   qt_tkhdr->pad  =    UTIL_Get_MSB_UShort(fin);
  693.  
  694.   if (qt_tkhdr->timescale) qt_tk_timescale = qt_tkhdr->timescale;
  695.   else qt_tk_timescale = qt_mv_timescale;
  696.  
  697.   DEBUG_LEVEL2
  698.   {
  699.     fprintf(stderr,"tk   ver = %lx  tk_id = %lx  timescale = %lx\n",
  700.     qt_tkhdr->version,qt_tkhdr->trackid,qt_tkhdr->timescale);
  701.     fprintf(stderr,"     dur= %lx timoff= %lx tk_width= %lx  tk_height= %lx\n",
  702.     qt_tkhdr->duration,qt_tkhdr->time_off,qt_tkhdr->tk_width,qt_tkhdr->tk_height);
  703.   }
  704. }
  705.  
  706.  
  707. void QT_Read_ELST(fin)
  708. FILE *fin;
  709. {
  710.  ULONG num,version;
  711.  
  712.  if (qts_samp_num==0) qts_init_duration = 0;
  713.  version = UTIL_Get_MSB_Long(fin);
  714.  num = UTIL_Get_MSB_Long(fin);
  715.  DEBUG_LEVEL2 fprintf(stderr,"    ELST ver %lx num %lx\n",version,num);
  716.  while(num--)
  717.  {
  718.    ULONG duration,time,rate,pad;
  719.    duration = UTIL_Get_MSB_Long(fin); 
  720.    time = UTIL_Get_MSB_Long(fin); 
  721.    rate = UTIL_Get_MSB_UShort(fin); 
  722.    pad  = UTIL_Get_MSB_UShort(fin); 
  723.    /* if 1st audio doesn't start at time 0 */
  724.    /* NOTE: this still won't work if there's a middle trak with no audio */
  725.    if ((qts_samp_num==0) && (time == 0xffffffff)) qts_init_duration += duration;
  726.  
  727.    DEBUG_LEVEL2 fprintf(stderr,"    -) dur %lx tim %lx rate %lx\n",
  728.         duration,time,rate);
  729.  }
  730. }
  731.  
  732. void QT_Read_MDHD(fin,qt_mdhdr)
  733. FILE *fin;
  734. QT_MDHDR *qt_mdhdr;
  735. {
  736.   qt_mdhdr->version =    UTIL_Get_MSB_Long(fin);
  737.   qt_mdhdr->creation =    UTIL_Get_MSB_Long(fin);
  738.   qt_mdhdr->modtime =    UTIL_Get_MSB_Long(fin);
  739.   qt_mdhdr->timescale =    UTIL_Get_MSB_Long(fin);
  740.   qt_mdhdr->duration =    UTIL_Get_MSB_Long(fin);
  741.   qt_mdhdr->language =    UTIL_Get_MSB_UShort(fin);
  742.   qt_mdhdr->quality =    UTIL_Get_MSB_UShort(fin);
  743.  
  744.   if (qt_mdhdr->timescale) qt_md_timescale = qt_mdhdr->timescale;
  745.   else qt_md_timescale = qt_tk_timescale;
  746.  
  747.   DEBUG_LEVEL2
  748.   {
  749.     fprintf(stderr,"md   ver = %lx  timescale = %lx  duration = %lx\n",
  750.     qt_mdhdr->version,qt_mdhdr->timescale,qt_mdhdr->duration);
  751.     fprintf(stderr,"     lang= %lx quality= %lx\n", 
  752.     qt_mdhdr->language,qt_mdhdr->quality);
  753.   }
  754. }
  755.  
  756.  
  757. void QT_Read_HDLR(fin,len,qt_hdlr_hdr)
  758. FILE *fin;
  759. LONG len;
  760. QT_HDLR_HDR *qt_hdlr_hdr;
  761. {
  762.   qt_hdlr_hdr->version =    UTIL_Get_MSB_Long(fin);
  763.   qt_hdlr_hdr->type =    UTIL_Get_MSB_Long(fin);
  764.   qt_hdlr_hdr->subtype =    UTIL_Get_MSB_Long(fin);
  765.   qt_hdlr_hdr->vendor =    UTIL_Get_MSB_Long(fin);
  766.   qt_hdlr_hdr->flags =    UTIL_Get_MSB_Long(fin);
  767.   qt_hdlr_hdr->mask =    UTIL_Get_MSB_Long(fin);
  768.  
  769.   DEBUG_LEVEL2
  770.   {
  771.     fprintf(stderr,"     ver = %lx  ",qt_hdlr_hdr->version);
  772.     QT_Print_ID(stderr,qt_hdlr_hdr->type,1);
  773.     QT_Print_ID(stderr,qt_hdlr_hdr->subtype,1);
  774.     QT_Print_ID(stderr,qt_hdlr_hdr->vendor,0);
  775.     fprintf(stderr,"\n     flags= %lx mask= %lx\n",
  776.     qt_hdlr_hdr->flags,qt_hdlr_hdr->mask);
  777.   }
  778.   /* Read Handler Name if Present */
  779.   if (len > 32)
  780.   {
  781.     len -= 32;
  782.     QT_Read_Name(fin,len);
  783.   }
  784. }
  785.  
  786.  
  787. /*********************************************
  788.  * Read and Parse Video Codecs
  789.  *
  790.  **********/
  791. void QT_Read_Video_STSD(fin)
  792. FILE *fin;
  793. { ULONG i,version,num,cur,sup;
  794.   version = UTIL_Get_MSB_Long(fin);
  795.   num = UTIL_Get_MSB_Long(fin);
  796.   DEBUG_LEVEL2 fprintf(stderr,"     ver = %lx  num = %lx\n", version,num);
  797.   if (qtv_codecs == 0)
  798.   { qtv_codec_num = num;
  799.     qtv_codecs = (QTV_CODEC_HDR *)malloc(qtv_codec_num * sizeof(QTV_CODEC_HDR));
  800.     if (qtv_codecs==0) TheEnd1("QT STSD: malloc err");
  801.     cur = 0;
  802.   }
  803.   else
  804.   { QTV_CODEC_HDR *tcodecs;
  805.     tcodecs = (QTV_CODEC_HDR *)malloc((qtv_codec_num+num) * sizeof(QTV_CODEC_HDR));
  806.     if (tcodecs==0) TheEnd1("QT STSD: malloc err");
  807.     for(i=0;i<qtv_codec_num;i++) tcodecs[i] = qtv_codecs[i];
  808.     cur = qtv_codec_num;
  809.     qtv_codec_num += num;
  810.     free(qtv_codecs);
  811.     qtv_codecs = tcodecs;
  812.   }
  813.   sup = 0;
  814.   for(i=0; i < num; i++)
  815.   {
  816.     sup |= QT_Read_Video_Codec_HDR( &qtv_codecs[cur], fin ); 
  817.     cur++;
  818.   }
  819.   /*POD NOTE: eventually make flag this back and return 0 */
  820.   if (sup == 0) TheEnd1("    QT codecs not supported - exiting.");
  821.   qt_video_flag = 1; 
  822.   if ( (qt_pic==0) && (xa_buffer_flag == TRUE))
  823.   {
  824.     qt_pic_size = qt_max_imagex * qt_max_imagey;
  825.     if ( (cmap_true_map_flag == TRUE) && (qt_depth > 8) )
  826.         qt_pic = (UBYTE *) malloc(3 * qt_pic_size);
  827.     else    qt_pic = (UBYTE *) malloc( XA_PIC_SIZE(qt_pic_size) );
  828.     if (qt_pic == 0) TheEnd1("QT_Buffer_Action: malloc failed");
  829.   }
  830. }
  831.  
  832.  
  833. ULONG QT_Read_Video_Codec_HDR(c_hdr,fin)
  834. QTV_CODEC_HDR *c_hdr;
  835. FILE *fin;
  836. {
  837.   ULONG id;
  838.   LONG len,i;
  839.   ULONG unk_0,unk_1,unk_2,unk_3,unk_4,unk_5,unk_6,unk_7,flag;
  840.   ULONG vendor,temp_qual,spat_qual,h_res,v_res;
  841.   
  842.   c_hdr->compression = 0;  /* used as support flag later */
  843.   len        = UTIL_Get_MSB_Long(fin);
  844.   id         = UTIL_Get_MSB_Long(fin);
  845.   unk_0        = UTIL_Get_MSB_Long(fin);
  846.   unk_1        = UTIL_Get_MSB_Long(fin);
  847.   unk_2        = UTIL_Get_MSB_UShort(fin);
  848.   unk_3        = UTIL_Get_MSB_UShort(fin);
  849.   vendor    = UTIL_Get_MSB_Long(fin);
  850.   temp_qual    = UTIL_Get_MSB_Long(fin);
  851.   spat_qual    = UTIL_Get_MSB_Long(fin);
  852.   qt_imagex    = UTIL_Get_MSB_UShort(fin);
  853.   qt_imagey    = UTIL_Get_MSB_UShort(fin);
  854.   h_res        = UTIL_Get_MSB_UShort(fin);
  855.   unk_4        = UTIL_Get_MSB_UShort(fin);
  856.   v_res        = UTIL_Get_MSB_UShort(fin);
  857.   unk_5        = UTIL_Get_MSB_UShort(fin);
  858.   unk_6        = UTIL_Get_MSB_Long(fin);
  859.   unk_7        = UTIL_Get_MSB_UShort(fin);
  860.   QT_Read_Name(fin,32);
  861.   qt_depth    = UTIL_Get_MSB_UShort(fin);
  862.   flag        = UTIL_Get_MSB_UShort(fin);
  863.   len -= 0x56;
  864.  
  865.   if (qt_depth == 8) /* generate colormap */
  866.   {
  867.     qt_imagec = 256;
  868.     QT_Create_Default_Cmap(qt_cmap);
  869.     if (!(flag & 0x08)) /* colormap isn't default */
  870.     {
  871.       ULONG start,end,p,r,g,b;
  872.       start = UTIL_Get_MSB_Long(fin); /* is this start or something else? */
  873.       end   = UTIL_Get_MSB_Long(fin); /* is this end or total number? */
  874.       len -= 8;
  875.       for(i = start; i <= end; i++)
  876.       {
  877.         p = UTIL_Get_MSB_UShort(fin); 
  878.         r = UTIL_Get_MSB_UShort(fin); 
  879.         g = UTIL_Get_MSB_UShort(fin); 
  880.         b = UTIL_Get_MSB_UShort(fin);  len -= 8;
  881.         if (p<qt_imagec)
  882.         {
  883.       qt_cmap[p].red   = r;
  884.       qt_cmap[p].green = g;
  885.       qt_cmap[p].blue  = b;
  886.         }
  887.         if (len <= 0) break;
  888.       }
  889.     } 
  890.   }
  891.  
  892.   while(len > 0) {fgetc(fin); len--; }
  893.  
  894.   if (xa_verbose) fprintf(stderr,"    Size %ldx%ld  Codec ",
  895.                         qt_imagex,qt_imagey);
  896.   switch(id)
  897.   {
  898.     case QT_rle:
  899.     if (xa_verbose) fprintf(stderr,"RLE depth %ld\n",qt_depth);
  900.     if (qt_depth == 8)
  901.     {
  902.       qt_compression = QT_CODEC_RLE;
  903.       qt_imagex = 4 * ((qt_imagex + 3)/4);
  904.     }
  905.     else if (qt_depth == 16) qt_compression = QT_CODEC_RLE16;
  906.     else if (qt_depth == 24) qt_compression = QT_CODEC_RLE24;
  907.     else if ( (qt_depth == 33) || (qt_depth == 1) )
  908.     {
  909.       qt_compression = QT_CODEC_RLE33;
  910.       qt_imagex = 16 * ((qt_imagex + 15)/16);
  911.       qt_depth = 1;
  912.     }
  913.     else { fprintf(stderr,"      unsupported\n"); return(0); }
  914.     break;
  915.     case QT_smc:
  916.     if (xa_verbose) fprintf(stderr,"SMC depth %ld\n",qt_depth);
  917.     if (qt_depth == 8)
  918.     {
  919.       qt_compression = QT_CODEC_SMC;
  920.       qt_imagex = 4 * ((qt_imagex + 3)/4);
  921.       qt_imagey = 4 * ((qt_imagey + 3)/4);
  922.     }
  923.     else { fprintf(stderr,"      unsupported\n"); return(0); }
  924.     break;
  925.     case QT_raw:
  926.     if (xa_verbose) fprintf(stderr,"RAW depth %ld\n",qt_depth);
  927.     if (qt_depth == 8) qt_compression = QT_CODEC_RAW;
  928.     else { fprintf(stderr,"      unsupported\n"); return(0); }
  929.     break;
  930.     case QT_rpza:
  931.     if (xa_verbose) fprintf(stderr,"RPZA depth %ld\n",qt_depth);
  932.     if (qt_depth == 16)
  933.     {
  934.       qt_compression = QT_CODEC_RPZA;
  935.       qt_imagex = 4 * ((qt_imagex + 3)/4);
  936.       qt_imagey = 4 * ((qt_imagey + 3)/4);
  937.     }
  938.     else { fprintf(stderr,"      unsupported\n"); return(0); }
  939.     break;
  940.     case QT_cvid:
  941.     if (xa_verbose) fprintf(stderr,"CVID depth %ld\n",qt_depth);
  942.     if ((qt_depth == 24) || (qt_depth == 32) )
  943.     {
  944.       QT_Gen_YUV_Tabs();
  945.       qt_compression = QT_CODEC_CVID;
  946.       qt_imagex = 4 * ((qt_imagex + 3)/4);
  947.       qt_imagey = 4 * ((qt_imagey + 3)/4);
  948.     }
  949.     else { fprintf(stderr,"      unsupported\n"); return(0); }
  950.     break;
  951.     case QT_jpeg:
  952.        fprintf(stderr,"JPEG unsupported\n",id); return(0); break;
  953.     case QT_SPIG:
  954.     if (xa_verbose) fprintf(stderr,"SPIG depth %ld\n",qt_depth);
  955.     goto QT_UNSUPPORTED;
  956. /*
  957.     QT_Gen_YUV_Tabs();
  958.     qt_compression = QT_CODEC_SPIG;
  959.     qt_imagex = 2 * ((qt_imagex + 1)/2);
  960.     qt_imagey = 2 * ((qt_imagey + 1)/2);
  961. */
  962.     break;
  963.     case QT_yuv2:
  964.     if (xa_verbose) fprintf(stderr,"YUV2 depth %ld\n",qt_depth);
  965.     QT_Gen_YUV_Tabs();
  966.     qt_compression = QT_CODEC_YUV2;
  967.     qt_imagex = 2 * ((qt_imagex + 1)/2);
  968.     qt_imagey = 2 * ((qt_imagey + 1)/2);
  969.     break;
  970.     default:
  971.     QT_UNSUPPORTED:
  972.     fprintf(stderr,"%08lx unknown\n",id);
  973.     return(0);
  974.     break;
  975.   }
  976.  
  977.   if (qt_depth == 1)
  978.   {
  979.     qt_imagec = 2;
  980.     qt_cmap[0].red = qt_cmap[0].green = qt_cmap[0].blue = 0; 
  981.     qt_cmap[1].red = qt_cmap[1].green = qt_cmap[1].blue = 0xff; 
  982.     qt_chdr = ACT_Get_CMAP(qt_cmap,qt_imagec,0,qt_imagec,0,8,8,8);
  983.   }
  984.   else if (qt_depth == 8)
  985.   {
  986.     qt_chdr = ACT_Get_CMAP(qt_cmap,qt_imagec,0,qt_imagec,0,16,16,16);
  987.   }
  988.   else if (qt_depth >= 16)
  989.   {
  990.     if (   (cmap_true_map_flag == FALSE) /* depth 16 and not true_map */
  991.            || (xa_buffer_flag == FALSE) )
  992.     {
  993.       if (cmap_true_to_332 == TRUE)
  994.         qt_chdr = CMAP_Create_332(qt_cmap,&qt_imagec);
  995.       else    qt_chdr = CMAP_Create_Gray(qt_cmap,&qt_imagec);
  996.     }
  997.     else { qt_imagec = 0; qt_chdr = 0; }
  998.   }
  999.   c_hdr->width    = qt_imagex;
  1000.   c_hdr->height    = qt_imagey;
  1001.   c_hdr->depth    = qt_depth;
  1002.   c_hdr->compression = qt_compression;
  1003.   c_hdr->chdr    = qt_chdr;
  1004.   if (qt_imagex > qt_max_imagex) qt_max_imagex = qt_imagex;
  1005.   if (qt_imagey > qt_max_imagey) qt_max_imagey = qt_imagey;
  1006.   return(1);
  1007. }
  1008.  
  1009. void QT_Read_Name(fin,r_len)
  1010. FILE *fin;
  1011. LONG r_len;
  1012. {
  1013.   ULONG len,d,i;
  1014.  
  1015.   len = fgetc(fin); r_len--;
  1016.   if (r_len == 0) r_len = len;
  1017.   if (len > r_len) fprintf(stderr,"QT_Name: len(%ld) > r_len(%ld)\n",len,r_len);
  1018.   DEBUG_LEVEL2 fprintf(stderr,"      (%ld/%ld) ",len,r_len);
  1019.   for(i=0;i<r_len;i++)
  1020.   {
  1021.     d = fgetc(fin);
  1022.     if (i < len) DEBUG_LEVEL2 fputc(d,stderr);
  1023.   }
  1024.   DEBUG_LEVEL2 fputc('\n',stderr);
  1025. }
  1026.  
  1027. /* Time To Sample */
  1028. void QT_Read_STTS(fin,len,qt_t2samp_num,qt_t2samps)
  1029. FILE *fin;
  1030. LONG len;
  1031. ULONG *qt_t2samp_num;
  1032. QT_T2SAMP_HDR **qt_t2samps;
  1033. {
  1034.   ULONG version,num,i,samp_cnt,duration,cur; 
  1035.   ULONG t2samp_num = *qt_t2samp_num;
  1036.   QT_T2SAMP_HDR *t2samps = *qt_t2samps;
  1037.  
  1038.   version    = UTIL_Get_MSB_Long(fin);
  1039.   num        = UTIL_Get_MSB_Long(fin);  len -= 8;
  1040.   DEBUG_LEVEL2 fprintf(stderr,"    ver=%lx num of entries = %lx\n",version,num);
  1041. /* POD TEST chunk len/num mismatch - deal with it - ignore given num??*/
  1042.   num = len >> 3;
  1043.   if (t2samps==0)
  1044.   {
  1045.     t2samp_num = num;
  1046.     t2samps = (QT_T2SAMP_HDR *)malloc(num * sizeof(QT_T2SAMP_HDR));
  1047.     if (t2samps==0) TheEnd1("QT_Read_STTS: malloc err");
  1048.     cur = 0;
  1049.   }
  1050.   else
  1051.   { QT_T2SAMP_HDR *t_t2samp;
  1052.     t_t2samp = (QT_T2SAMP_HDR *)
  1053.             malloc((t2samp_num + num) * sizeof(QT_T2SAMP_HDR));
  1054.     if (t_t2samp==0) TheEnd1("QT_Read_STTS: malloc err");
  1055.     for(i=0;i<t2samp_num;i++) t_t2samp[i] = t2samps[i];
  1056.     cur = t2samp_num;
  1057.     t2samp_num += num;
  1058.     free(t2samps);
  1059.     t2samps = t_t2samp;
  1060.   }
  1061.   for(i=0;i<num;i++)
  1062.   { double ftime;
  1063.     samp_cnt    = UTIL_Get_MSB_Long(fin);
  1064.     duration    = UTIL_Get_MSB_Long(fin);  len -= 8;
  1065.     if (duration == 0) duration = 1;
  1066.     /* NOTE: convert to 1000ms per second */
  1067.     t2samps[cur].cnt = samp_cnt;
  1068.     ftime = (1000.0 * (double)(duration)) / (double)(qt_timescale);
  1069.     t2samps[cur].time = (ULONG)(ftime);
  1070.     ftime -= (double)(t2samps[cur].time);
  1071.     t2samps[cur].timelo = (ULONG)(ftime * (double)(1<<24));
  1072.     DEBUG_LEVEL2 fprintf(stderr,"      %ld) samp_cnt=%lx duration = %lx time %ld timelo %ld ftime %lf\n",
  1073.     i,samp_cnt,duration,t2samps[cur].time,t2samps[cur].timelo,ftime);
  1074.     cur++;
  1075.   }
  1076.   *qt_t2samp_num = t2samp_num;
  1077.   *qt_t2samps = t2samps;
  1078.   while(len > 0) {len--; getc(fin); }
  1079. }
  1080.  
  1081.  
  1082. /* Sync Sample */
  1083. void QT_Read_STSS(fin)
  1084. FILE *fin;
  1085. {
  1086.   ULONG version,num,i,j;
  1087.   version    = UTIL_Get_MSB_Long(fin);
  1088.   num        = UTIL_Get_MSB_Long(fin);
  1089.   DEBUG_LEVEL2 
  1090.   {
  1091.     fprintf(stderr,"    ver=%lx num of entries = %lx\n",version,num);
  1092.     j = 0;
  1093.     fprintf(stderr,"      ");
  1094.   }
  1095.   for(i=0;i<num;i++)
  1096.   {
  1097.     ULONG samp_num;
  1098.     samp_num    = UTIL_Get_MSB_Long(fin);
  1099.     DEBUG_LEVEL2
  1100.     {
  1101.       fprintf(stderr,"%lx ",samp_num); j++;
  1102.       if (j >= 8) {fprintf(stderr,"\n      "); j=0; }
  1103.     }
  1104.   }
  1105.   DEBUG_LEVEL2 fprintf(stderr,"\n");
  1106. }
  1107.  
  1108.  
  1109. /* Sample to Chunk */
  1110. void QT_Read_STSC(fin,len,qt_s2chunk_num,qt_s2chunks,
  1111.         chunkoff_lstnum,codec_num,codec_lstnum)
  1112. FILE *fin;
  1113. LONG len;
  1114. ULONG *qt_s2chunk_num;
  1115. QT_S2CHUNK_HDR **qt_s2chunks;
  1116. ULONG chunkoff_lstnum,codec_num,codec_lstnum;
  1117. {
  1118.   ULONG version,num,i,cur,stsc_type,last;
  1119.   ULONG s2chunk_num = *qt_s2chunk_num;
  1120.   QT_S2CHUNK_HDR *s2chunks = *qt_s2chunks;
  1121.  
  1122.   version    = UTIL_Get_MSB_Long(fin);
  1123.   num        = UTIL_Get_MSB_Long(fin);    len -= 16;
  1124.   i = (num)?(len/num):(0);
  1125.   if (i == 16) 
  1126.   { 
  1127.     DEBUG_LEVEL2 fprintf(stderr,"STSC: OLD STYLE\n");
  1128.     len -= num * 16; stsc_type = 0;
  1129.   }
  1130.   else 
  1131.   { 
  1132.     DEBUG_LEVEL2 fprintf(stderr,"STSC: NEW STYLE\n");
  1133.     len -= num * 12; stsc_type = 1;
  1134.   }
  1135.  
  1136.   DEBUG_LEVEL2 fprintf(stderr,"    ver=%lx num of entries = %lx\n",version,num);
  1137.   if (s2chunks == 0)
  1138.   {
  1139.     s2chunk_num = num;
  1140.     s2chunks = (QT_S2CHUNK_HDR *)malloc((num+1) * sizeof(QT_S2CHUNK_HDR));
  1141.     cur = 0;
  1142.   }
  1143.   else
  1144.   { QT_S2CHUNK_HDR *ts2c;
  1145.     ts2c = (QT_S2CHUNK_HDR *)
  1146.     malloc( (s2chunk_num + num + 1) * sizeof(QT_S2CHUNK_HDR));
  1147.     for(i=0;i<s2chunk_num;i++) ts2c[i] = s2chunks[i];
  1148.     cur = s2chunk_num;
  1149.     s2chunk_num += num;
  1150.     free(s2chunks);
  1151.     s2chunks = ts2c;
  1152.   }
  1153.   last = 0;
  1154.   for(i=0;i<num;i++)
  1155.   {
  1156.     ULONG first_chk,samp_per,chunk_tag;
  1157.     if (stsc_type == 0)  /* 4 entries */
  1158.     { ULONG tmp;
  1159.       first_chk    = UTIL_Get_MSB_Long(fin);
  1160.       tmp    = UTIL_Get_MSB_Long(fin);
  1161.       samp_per    = UTIL_Get_MSB_Long(fin);
  1162.       chunk_tag    = UTIL_Get_MSB_Long(fin);
  1163.       if (i > 0) s2chunks[cur-1].num   = first_chk - last;
  1164.       last = first_chk;
  1165.       if (i==(num-1))
  1166.       {
  1167.     if (qt_stgs_num)
  1168.     {
  1169.       s2chunks[cur].num   = (qt_stgs_num - first_chk) + 1;
  1170.       qt_stgs_num = 0;
  1171.         }
  1172.     else 
  1173.     {
  1174.       fprintf(stderr,"STSC: old style but not stgs chunk warning\n");
  1175.       s2chunks[cur].num = 100000;
  1176.     }
  1177.       }
  1178.     }
  1179.     else        /* 3 entries */
  1180.     {
  1181.       first_chk    = UTIL_Get_MSB_Long(fin);
  1182.       samp_per    = UTIL_Get_MSB_Long(fin);
  1183.       chunk_tag    = UTIL_Get_MSB_Long(fin);
  1184.       s2chunks[cur].num   = samp_per;
  1185.     }
  1186.     DEBUG_LEVEL2 
  1187.      fprintf(stderr,"      %ld-%ld) first_chunk=%lx samp_per_chk=%lx chk_tag=%lx\n",
  1188.                     i,cur,first_chk,samp_per,chunk_tag);
  1189.         /* start at 0 not 1  and account for previous chunks */
  1190.     s2chunks[cur].first = first_chk - 1 + chunkoff_lstnum;
  1191.     if (chunk_tag > (codec_num - codec_lstnum)) 
  1192.     { samp_per = chunk_tag = 1; }
  1193.     s2chunks[cur].tag   = chunk_tag - 1 + codec_lstnum;
  1194.     cur++;
  1195.   }
  1196.   s2chunks[cur].first = 0;
  1197.   s2chunks[cur].num   = 0;
  1198.   s2chunks[cur].tag   = 0;
  1199.   DEBUG_LEVEL2 fprintf(stderr,"    STSC left over %ld\n",len);
  1200.   while (len > 0) { fgetc(fin); len--; }
  1201.   *qt_s2chunk_num = s2chunk_num;
  1202.   *qt_s2chunks = s2chunks;
  1203. }
  1204.  
  1205. /* Sample Size */
  1206. void QT_Read_STSZ(fin,len,qt_samp_num,qt_samp_sizes)
  1207. FILE *fin;
  1208. LONG len;
  1209. ULONG *qt_samp_num,**qt_samp_sizes;
  1210. {
  1211.   ULONG version,samp_size,num,i,cur;
  1212.   ULONG samp_num   = *qt_samp_num;
  1213.   ULONG *samp_sizes = *qt_samp_sizes;
  1214.  
  1215.   version    = UTIL_Get_MSB_Long(fin);
  1216.   samp_size    = UTIL_Get_MSB_Long(fin);
  1217.   num        = UTIL_Get_MSB_Long(fin);
  1218.   len = (len - 20) / 4;   /* number of stored samples */
  1219.   DEBUG_LEVEL2 fprintf(stderr,"    ver=%lx samp_size=%lx entries= %lx stored entries=%lx\n",version,samp_size,num,len);
  1220.  
  1221.   if (samp_size == 1) num = 1; /* for AUDIO PODNOTE: rethink this */
  1222.   if (samp_sizes == 0)
  1223.   {
  1224.     samp_num = num;
  1225.     samp_sizes = (ULONG *)malloc(num * sizeof(ULONG));
  1226.     if (samp_sizes == 0) {fprintf(stderr,"malloc err 0\n"); exit(0);}
  1227.     cur = 0;
  1228.   }
  1229.   else /*TRAK*/
  1230.   {
  1231.     ULONG *tsamps;
  1232.     tsamps = (ULONG *)malloc((samp_num + num) * sizeof(ULONG));
  1233.     if (tsamps == 0) {fprintf(stderr,"malloc err 0\n"); exit(0);}
  1234.     for(i=0; i<samp_num; i++) tsamps[i] = samp_sizes[i];
  1235.     cur = samp_num;
  1236.     samp_num += num;
  1237.     free(samp_sizes);
  1238.     samp_sizes = tsamps;
  1239.   }
  1240.   for(i=0;i<num;i++) 
  1241.   {
  1242.     if (i < len) samp_sizes[cur] = UTIL_Get_MSB_Long(fin);
  1243.     else if (i==0) samp_sizes[cur] = samp_size;
  1244.            else samp_sizes[cur] = samp_sizes[cur-1];
  1245.     cur++;
  1246.   }
  1247.   *qt_samp_num = samp_num;
  1248.   *qt_samp_sizes = samp_sizes;
  1249. }
  1250.  
  1251. /* Chunk Offset */
  1252. void QT_Read_STCO(fin,qt_chunkoff_num,qt_chunkoffs)
  1253. FILE *fin;
  1254. ULONG *qt_chunkoff_num;
  1255. ULONG **qt_chunkoffs;
  1256. {
  1257.   ULONG version,num,i,cur;
  1258.   ULONG chunkoff_num = *qt_chunkoff_num;
  1259.   ULONG *chunkoffs = *qt_chunkoffs;
  1260.  
  1261.   version    = UTIL_Get_MSB_Long(fin);
  1262.   num        = UTIL_Get_MSB_Long(fin);
  1263.   DEBUG_LEVEL2 fprintf(stderr,"    ver=%lx entries= %lx\n",version,num);
  1264.   if (chunkoffs == 0)
  1265.   {
  1266.     chunkoff_num = num;
  1267.     chunkoffs = (ULONG *)malloc(num * sizeof(ULONG) );
  1268.     cur = 0;
  1269.   }
  1270.   else
  1271.   {
  1272.     ULONG *tchunks;
  1273.     tchunks = (ULONG *)malloc((chunkoff_num + num) * sizeof(ULONG));
  1274.     if (tchunks == 0) {fprintf(stderr,"malloc err 0\n"); exit(0);}
  1275.     for(i=0; i<chunkoff_num; i++) tchunks[i] = chunkoffs[i];
  1276.     cur = chunkoff_num;
  1277.     chunkoff_num += num;
  1278.     free(chunkoffs);
  1279.     chunkoffs = tchunks;
  1280.   }
  1281.   for(i=0;i<num;i++) {chunkoffs[cur] = UTIL_Get_MSB_Long(fin); cur++; }
  1282.   *qt_chunkoff_num = chunkoff_num;
  1283.   *qt_chunkoffs = chunkoffs;
  1284. }
  1285.  
  1286.  
  1287.  
  1288. void QT_Read_Video_Data(fin,anim_hdr)
  1289. FILE *fin;
  1290. XA_ANIM_HDR *anim_hdr;
  1291. {
  1292.   ULONG d,ret,base_offset,i;
  1293.   ULONG cur_samp,cur_s2chunk,nxt_s2chunk;
  1294.   ULONG cur_t2samp,nxt_t2samp;
  1295.   ULONG tag;
  1296.   ULONG olast;
  1297.   ULONG cmap_frame_num;
  1298.   XA_ACTION *act;
  1299.  
  1300.   if (qtv_samp_sizes == 0) {fprintf(stderr,"no samples\n"); return; } 
  1301.   base_offset = 0;
  1302.  
  1303.   cmap_frame_num = qtv_chunkoff_num / cmap_sample_cnt;
  1304.  
  1305.   nxt_t2samp = cur_t2samp = 0;
  1306.   if (qtv_t2samps)
  1307.   {
  1308.     if (xa_jiffy_flag) { qt_time = xa_jiffy_flag; qt_timelo = 0; }
  1309.     else
  1310.     { 
  1311.       qt_time   = qtv_t2samps[cur_t2samp].time;
  1312.       qt_timelo = qtv_t2samps[cur_t2samp].timelo;
  1313.     }
  1314.     nxt_t2samp += qtv_t2samps[cur_t2samp].cnt;
  1315.   } else { qt_time = XA_GET_TIME(100); qt_timelo = 0; }
  1316.  
  1317.   olast=0;
  1318.   cur_samp = 0;
  1319.   cur_s2chunk = 0;
  1320.   nxt_s2chunk = qtv_s2chunks[cur_s2chunk + 1].first;
  1321.   tag =  qtv_s2chunks[cur_s2chunk].tag;
  1322.   qt_imagex = qtv_codecs[tag].width;
  1323.   qt_imagey = qtv_codecs[tag].height;
  1324.   qt_depth  = qtv_codecs[tag].depth;
  1325.   qt_compression  = qtv_codecs[tag].compression;
  1326.   qt_chdr   = qtv_codecs[tag].chdr;
  1327.   /* KLUDGE FOR Lem_Separation */
  1328. /*
  1329.   if (qtv_samp_num == qtv_chunkoff_num) nxt_s2chunk = qtv_chunkoff_num + 1;
  1330. */
  1331.   /* Loop through chunk offsets */
  1332.   for(i=0; i < qtv_chunkoff_num; i++)
  1333.   {
  1334.     ULONG size,off,num_samps;
  1335.     ACT_DLTA_HDR *dlta_hdr;
  1336.  
  1337.     off =  base_offset + qtv_chunkoffs[i];
  1338.         /* survive RPZA despite corruption(offsets commonly corrupted).*/
  1339.     if (qt_compression == QT_CODEC_RPZA)
  1340.     { ULONG check;
  1341.       fseek(fin,off,0); check = UTIL_Get_MSB_Long(fin) & 0x00ffffff;
  1342.       if (check != qtv_samp_sizes[cur_samp])
  1343.       {
  1344.         fseek(fin,olast,0); check = UTIL_Get_MSB_Long(fin) & 0x00ffffff;
  1345.         if (check == qtv_samp_sizes[cur_samp]) off = olast;
  1346.       }
  1347.     }
  1348.     olast = off;
  1349.     fseek(fin,off,0);  /* move to start of chunk data */
  1350.  
  1351. DEBUG_LEVEL2 fprintf(stderr,"T2S: cur-t2 %ld cur-smp %ld nxt-t2 %ld tot t2 %ld\n", cur_t2samp,cur_samp,nxt_t2samp,qtv_t2samp_num);
  1352.     if ( (cur_samp >= nxt_t2samp) && (cur_t2samp < qtv_t2samp_num) )
  1353.     {
  1354.       cur_t2samp++;
  1355.       if (xa_jiffy_flag) { qt_time = xa_jiffy_flag; qt_timelo = 0; }
  1356.       else
  1357.       { 
  1358.     qt_time   = qtv_t2samps[cur_t2samp].time;
  1359.     qt_timelo = qtv_t2samps[cur_t2samp].timelo;
  1360.       }
  1361.       nxt_t2samp += qtv_t2samps[cur_t2samp].cnt;
  1362.     }
  1363.  
  1364.     if ( (i == nxt_s2chunk) && ((cur_s2chunk+1) < qtv_s2chunk_num) )
  1365.     {
  1366.       cur_s2chunk++;
  1367.       nxt_s2chunk = qtv_s2chunks[cur_s2chunk + 1].first;
  1368.     }
  1369.     num_samps = qtv_s2chunks[cur_s2chunk].num;
  1370.  
  1371.     /* Check tags and possibly move to new codec */
  1372.     if (qtv_s2chunks[cur_s2chunk].tag >= qtv_codec_num) 
  1373.     {
  1374.       fprintf(stderr,"QT Data: Warning stsc chunk invalid %ld tag %ld\n",
  1375.         cur_s2chunk,qtv_s2chunks[cur_s2chunk].tag);
  1376.     } 
  1377.     else if (qtv_s2chunks[cur_s2chunk].tag != tag)
  1378.     {
  1379.       tag =  qtv_s2chunks[cur_s2chunk].tag;
  1380.       qt_imagex = qtv_codecs[tag].width;
  1381.       qt_imagey = qtv_codecs[tag].height;
  1382.       qt_depth  = qtv_codecs[tag].depth;
  1383.       qt_compression  = qtv_codecs[tag].compression;
  1384.       qt_chdr   = qtv_codecs[tag].chdr;
  1385.     }
  1386.  
  1387.     /* Read number of samples in each chunk */
  1388.     while(num_samps--)
  1389.     {
  1390.       size = qtv_samp_sizes[cur_samp];
  1391.       olast += size;
  1392.  
  1393.       /* QT_Codec_List(fin,size);  for decoding only */
  1394.       DEBUG_LEVEL2 fprintf(stderr,"CODEC %lx) size = %lx offset = %lx\n",
  1395.         i,size,off);
  1396. /*
  1397. fprintf(stderr,"CODEC %lx %ld) size = %lx offset = %lx samp %ld\n",
  1398.         i,cur_samp,size,off,num_samps);
  1399. */
  1400.  
  1401.       act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  1402.       if (xa_file_flag == TRUE)
  1403.       {
  1404.     dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
  1405.     if (dlta_hdr == 0) TheEnd1("QT rle: malloc failed");
  1406.     act->data = (UBYTE *)dlta_hdr;
  1407.     dlta_hdr->flags = ACT_SNGL_BUF;
  1408.     dlta_hdr->fsize = size;
  1409.     dlta_hdr->fpos  = ftell(fin);
  1410.     fseek(fin,size,1); /* move past this chunk */
  1411.     if (size > qt_max_fsize) qt_max_fsize = size;
  1412.       }
  1413.       else
  1414.       {
  1415.     d = size + (sizeof(ACT_DLTA_HDR));
  1416.     dlta_hdr = (ACT_DLTA_HDR *) malloc( d );
  1417.     if (dlta_hdr == 0) TheEnd1("QT rle: malloc failed");
  1418.     act->data = (UBYTE *)dlta_hdr;
  1419.     dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  1420.     dlta_hdr->fpos = 0; dlta_hdr->fsize = size;
  1421.     ret = fread( dlta_hdr->data, size, 1, fin);
  1422.     if (ret != 1) TheEnd1("QT codec: read failed");
  1423.       }
  1424.  
  1425.       QT_Add_Frame(qt_time,qt_timelo,act);
  1426.       dlta_hdr->xpos = dlta_hdr->ypos = 0;
  1427.       dlta_hdr->xsize = qt_imagex;
  1428.       dlta_hdr->ysize = qt_imagey;
  1429.       dlta_hdr->special = 0;
  1430.       dlta_hdr->extra = 0;
  1431.       switch(qt_compression)
  1432.       {
  1433.         case QT_CODEC_SPIG:  dlta_hdr->delta = QT_Decode_SPIG; break;
  1434.         case QT_CODEC_YUV2:  dlta_hdr->delta = QT_Decode_YUV2; break;
  1435.         case QT_CODEC_RLE:   dlta_hdr->delta = QT_Decode_RLE; break;
  1436.         case QT_CODEC_RLE16: dlta_hdr->delta = QT_Decode_RLE16; break;
  1437.         case QT_CODEC_RLE24: dlta_hdr->delta = QT_Decode_RLE24; break;
  1438.         case QT_CODEC_RLE33: dlta_hdr->delta = QT_Decode_RLE33; break;
  1439.         case QT_CODEC_RAW:   dlta_hdr->delta = QT_Decode_RAW; break;
  1440.         case QT_CODEC_RPZA:  dlta_hdr->delta = QT_Decode_RPZA; break;
  1441.         case QT_CODEC_CVID:  dlta_hdr->delta = QT_Decode_CVID; break;
  1442.         case QT_CODEC_SMC:   dlta_hdr->delta = QT_Decode_SMC; break;
  1443.         default:
  1444.           fprintf(stderr,"QT: unsupported comp ");
  1445.           QT_Print_ID(stderr,qt_compression,1); 
  1446.       fprintf(stderr,"depth=%ld\n",qt_depth);
  1447.           act->type = ACT_NOP;
  1448.           break;
  1449.       } /* end of compression types */
  1450.  
  1451.       if ( (xa_buffer_flag == TRUE) && (act->type != ACT_NOP) )
  1452.       {
  1453.     ULONG xpos,ypos,xsize,ysize,dlta_flag;
  1454.         if ( (cmap_true_map_flag==FALSE) || (qt_depth <= 8) )
  1455.     {
  1456.       ULONG map_flag = (x11_display_type & XA_X11_TRUE)?(TRUE):(FALSE);
  1457.       dlta_flag = dlta_hdr->delta(qt_pic,dlta_hdr->data,dlta_hdr->fsize,
  1458.         0,qt_chdr->map,map_flag, qt_imagex,qt_imagey,8,
  1459.         &xpos,&ypos,&xsize,&ysize,0,0);
  1460.       if (!(dlta_flag & ACT_DLTA_MAPD)) map_flag = FALSE;
  1461.       xsize -= xpos; ysize -= ypos;
  1462.       FREE(dlta_hdr,0x9001); act->data = 0; dlta_hdr = 0;
  1463.       if (dlta_flag & ACT_DLTA_NOP) act->type = ACT_NOP;
  1464.       else ACT_Setup_Mapped(act,qt_pic,qt_chdr,xpos,ypos,xsize,ysize,
  1465.         qt_imagex,qt_imagey,FALSE,0, FALSE,TRUE,map_flag);
  1466.           ACT_Add_CHDR_To_Action(act,qt_chdr);
  1467.     }
  1468.     else /* decode as RGB triplets and then convert to mapped image */
  1469.     {
  1470.           UBYTE *tpic;
  1471.       dlta_flag = dlta_hdr->delta(qt_pic,dlta_hdr->data,dlta_hdr->fsize,
  1472.         0,0,FALSE,qt_imagex,qt_imagey,8,&xpos,&ypos,&xsize,&ysize,1,0);
  1473. /*POD NOTE: need to add subimage support to RGB conversion utils */
  1474.       FREE(dlta_hdr,0x9002); act->data = 0; dlta_hdr = 0;
  1475.       if (dlta_flag & ACT_DLTA_NOP) act->type = ACT_NOP;
  1476.       else
  1477.       {
  1478.         xpos = ypos = 0; xsize = qt_imagex; ysize = qt_imagey;
  1479.         /* xsize -= xpos; ysize -= ypos; */
  1480.         if (    (cmap_true_to_all == TRUE)
  1481.             || ((cmap_true_to_1st == TRUE) && (qt_chdr == 0) )
  1482.            )    qt_chdr = CMAP_Create_CHDR_From_True(qt_pic,8,8,8,
  1483.                 qt_imagex,qt_imagey,qt_cmap,&qt_imagec);
  1484.         else if ( (cmap_true_to_332 == TRUE) && (qt_chdr == 0) )
  1485.             qt_chdr = CMAP_Create_332(qt_cmap,&qt_imagec);
  1486.         else if ( (cmap_true_to_gray == TRUE) && (qt_chdr == 0) )
  1487.             qt_chdr = CMAP_Create_Gray(qt_cmap,&qt_imagec);
  1488.  
  1489.         if (cmap_dither_type == CMAP_DITHER_FLOYD)
  1490.         tpic = UTIL_RGB_To_FS_Map(0,qt_pic,qt_chdr,
  1491.                     qt_imagex,qt_imagey,FALSE);
  1492.         else
  1493.         tpic = UTIL_RGB_To_Map(0,qt_pic,qt_chdr,
  1494.                     qt_imagex,qt_imagey,FALSE);
  1495.         ACT_Setup_Mapped(act,tpic,qt_chdr,xpos,ypos,xsize,ysize,
  1496.         qt_imagex,qt_imagey,FALSE,0,TRUE,TRUE,FALSE);
  1497.             ACT_Add_CHDR_To_Action(act,qt_chdr);
  1498.       } /* end of not NOP */
  1499.     } /* end of true_map */
  1500.       } /* end of buffer */
  1501.       else  /* not buffered */
  1502.       {
  1503.         /* Also make sure not TRUE, is 332 and special case file_flag */
  1504.         if ( (cmap_color_func != 0)
  1505.             && (qt_depth > 8) && (!(x11_display_type & XA_X11_TRUE)) )
  1506.         { 
  1507.         if (qt_cmap_flag == 0)
  1508.         {
  1509.       ULONG xpos,ypos,xsize,ysize,dlta_flag,psize;
  1510.       UBYTE *cbuf,*data;
  1511.  
  1512.       psize = qt_imagex * qt_imagey;
  1513.       cbuf = (UBYTE *) malloc(3 * psize);
  1514.           if (cbuf == 0) TheEnd1("colorfunc1 malloc err0\n");
  1515.       memset((char *)(cbuf),0x00,(3 * psize) );
  1516.  
  1517.       if (xa_file_flag == TRUE)
  1518.       { ULONG pos;
  1519.         data = (UBYTE *)malloc(dlta_hdr->fsize);
  1520.         if (data==0) TheEnd1("colorfunc1 malloc err1\n");
  1521.         pos = ftell(fin); 
  1522.         fseek(fin,dlta_hdr->fpos,0); /* save file pos */
  1523.         fread(data,dlta_hdr->fsize,1,fin); /* read data*/
  1524.         fseek(fin,pos,0); /* restore file pos */
  1525.       } else data = dlta_hdr->data;
  1526.           dlta_flag = dlta_hdr->delta(cbuf,data,dlta_hdr->fsize,
  1527.                 0,0,FALSE,qt_imagex,qt_imagey,8,&xpos,&ypos,&xsize,&ysize,1,0);
  1528.       if (xa_file_flag == TRUE) { free(data); data = 0; }
  1529.  
  1530.      switch(cmap_color_func)
  1531.      {
  1532.       case 4:
  1533.       {
  1534.             qt_chdr = CMAP_Create_CHDR_From_True(cbuf,8,8,8,
  1535.                               qt_imagex,qt_imagey,qt_cmap,&qt_imagec);
  1536.             DEBUG_LEVEL1 fprintf(stderr,"CF4: csize = %ld\n",qt_chdr->csize);
  1537.             if (qt_chdr->csize > 128) qt_cmap_flag = 1;
  1538.             if (cbuf) free(cbuf); cbuf = 0;
  1539.       }
  1540.       break;
  1541.          } /* end of switch */
  1542.         } /* first time through */
  1543.         else  /* else cnt til next time */
  1544.         {
  1545.           qt_cmap_cnt++;
  1546.           if (cmap_sample_cnt && (qt_cmap_cnt >= cmap_frame_num))
  1547.             { qt_cmap_flag = 0; qt_cmap_cnt = 0; }
  1548.         }
  1549.         } /* color func, true color anim and not True Display  */
  1550.         ACT_Add_CHDR_To_Action(act,qt_chdr);
  1551.       }
  1552.       cur_samp++;
  1553.       if (cur_samp >= qtv_samp_num) break;
  1554.     } /* end of sample number */
  1555.     if (cur_samp >= qtv_samp_num) break;
  1556.   } /* end of chunk_offset loop */
  1557. }
  1558.  
  1559.  
  1560. ULONG
  1561. QT_Decode_RLE(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  1562.                     xs,ys,xe,ye,special,extra)
  1563. UBYTE *image;           /* Image Buffer. */
  1564. UBYTE *delta;           /* delta data. */
  1565. ULONG dsize;            /* delta size */
  1566. XA_CHDR *tchdr;        /* color map info */
  1567. ULONG *map;             /* used if it's going to be remapped. */
  1568. ULONG map_flag;         /* whether or not to use remap_map info. */
  1569. ULONG imagex,imagey;    /* Size of image buffer. */
  1570. ULONG imaged;           /* Depth of Image. (IFF specific) */
  1571. ULONG *xs,*ys;          /* pos of changed area. */
  1572. ULONG *xe,*ye;          /* size of changed area. */
  1573. ULONG special;          /* Special Info. */
  1574. ULONG extra;        /* extra info needed to decode delta */
  1575. {
  1576.   LONG y,lines,d; /* LONG min_x,max_x,min_y,max_y;  */
  1577.   UBYTE *dptr;
  1578.  
  1579.   dptr = delta;
  1580.   dptr += 4;    /* skip codec size */
  1581.   d = (*dptr++) << 8;  d |= *dptr++;   /* read code either 0008 or 0000 */
  1582.   if (d == 0x0000) /* NOP frame? */
  1583.   { /* There is one more byte 0x00 that I don't read in this case */
  1584.     *xs = *ys = *xe = *ye = 0;
  1585.     return(ACT_DLTA_NOP);
  1586.   }
  1587.   y = (*dptr++) << 8; y |= *dptr++;        /* start line */
  1588.   dptr += 2;                    /* unknown */
  1589.   lines = (*dptr++) << 8; lines |= *dptr++;    /* number of lines */
  1590.   dptr += 2;                    /* unknown */
  1591.   while(lines--)
  1592.   {
  1593.     ULONG xskip,cnt;
  1594.     xskip = *dptr++;                /* skip x pixels */
  1595.     cnt = *dptr++;                /* RLE code */
  1596.     if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  1597.     { UBYTE *iptr = (UBYTE *)(image + (y * imagex) + (4 * (xskip-1)) );
  1598.       while(cnt != 0xff)
  1599.       {
  1600.         if (cnt == 0x00) { xskip = *dptr++; iptr += 4 * (xskip-1); }
  1601.         else if (cnt < 0x80)            /* run of data */
  1602.         {
  1603.           cnt *= 4; if (map_flag==FALSE) while(cnt--) *iptr++ = (UBYTE)*dptr++;
  1604.           else while(cnt--) *iptr++ = (UBYTE)map[*dptr++];
  1605.         } else                    /* repeat data */
  1606.         { UBYTE d1,d2,d3,d4;    cnt = 0x100 - cnt;
  1607.           if (map_flag==TRUE) { d1=(UBYTE)map[*dptr++]; d2=(UBYTE)map[*dptr++];
  1608.                   d3=(UBYTE)map[*dptr++]; d4=(UBYTE)map[*dptr++]; }
  1609.       else    { d1 = (UBYTE)*dptr++; d2 = (UBYTE)*dptr++;
  1610.           d3 = (UBYTE)*dptr++; d4 = (UBYTE)*dptr++; }
  1611.           while(cnt--) { *iptr++ =d1; *iptr++ =d2; *iptr++ =d3; *iptr++ =d4; }
  1612.         } /* end of  >= 0x80 */
  1613.         cnt = *dptr++;
  1614.       } /* end while cnt */
  1615.     } else if (x11_bytes_pixel==2)
  1616.     { USHORT *iptr = (USHORT *)(image + 2 *((y * imagex) + (4 * (xskip-1))) );
  1617.       while(cnt != 0xff)
  1618.       {
  1619.         if (cnt == 0x00) { xskip = *dptr++; iptr += 4 * (xskip-1); }
  1620.         else if (cnt < 0x80)            /* run of data */
  1621.         {
  1622.           cnt *= 4; while(cnt--) *iptr++ = (USHORT)map[*dptr++];
  1623.         } else                    /* repeat data */
  1624.         { USHORT d1,d2,d3,d4;    cnt = 0x100 - cnt;
  1625.       { d1 = (USHORT)map[*dptr++]; d2 = (USHORT)map[*dptr++];
  1626.         d3 = (USHORT)map[*dptr++]; d4 = (USHORT)map[*dptr++]; }
  1627.           while(cnt--) { *iptr++ =d1; *iptr++ =d2; *iptr++ =d3; *iptr++ =d4; }
  1628.         } /* end of  >= 0x80 */
  1629.         cnt = *dptr++;
  1630.       } /* end while cnt */
  1631.     } else /* bytes == 4 */
  1632.     { ULONG *iptr = (ULONG *)(image + 4 * ((y * imagex) + (4 * (xskip-1))) );
  1633.       while(cnt != 0xff)
  1634.       {
  1635.         if (cnt == 0x00) { xskip = *dptr++; iptr += 4 * (xskip-1); }
  1636.         else if (cnt < 0x80)            /* run of data */
  1637.         {
  1638.           cnt *= 4; while(cnt--) *iptr++ = (ULONG)map[*dptr++];
  1639.         } else                    /* repeat data */
  1640.         { ULONG d1,d2,d3,d4; cnt = 0x100 - cnt;
  1641.       { d1 = (ULONG)map[*dptr++]; d2 = (ULONG)map[*dptr++]; 
  1642.         d3 = (ULONG)map[*dptr++]; d4 = (ULONG)map[*dptr++]; }
  1643.           while(cnt--) { *iptr++ =d1; *iptr++ =d2; *iptr++ =d3; *iptr++ =d4; }
  1644.         } /* end of  >= 0x80 */
  1645.         cnt = *dptr++;
  1646.       } /* end while cnt */
  1647.     }
  1648.     y++;
  1649.   } /* end of lines */
  1650.  /* one more zero byte */
  1651.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  1652.  if (map_flag==TRUE) return(ACT_DLTA_MAPD);
  1653.  else return(ACT_DLTA_NORM);
  1654. }
  1655.  
  1656. ULONG QT_Parse_Bin(fin)
  1657. FILE *fin;
  1658. {
  1659.   ULONG pos,len,csize,cid,total;
  1660.  
  1661.   fseek(fin,0,2);
  1662.   total = ftell(fin);
  1663.  
  1664. /* Read over Header */
  1665.   fseek(fin,0,0);
  1666.   pos = len = UTIL_Get_MSB_Long(fin);
  1667.   cid = UTIL_Get_MSB_Long(fin);
  1668.   if (cid == QT_mdat)
  1669.   {
  1670.     fseek(fin,0,0);
  1671.     if (len == 0)
  1672.     {
  1673.       fprintf(stderr,"QT: This is only .data fork. Need .rsrc fork\n");
  1674.       return(0);
  1675.     }
  1676.     else return(1);
  1677.   }
  1678.  
  1679. DEBUG_LEVEL1 fprintf(stderr,"QT_Parse_Bin: %lx\n",pos);
  1680.  
  1681.   while( pos < total )
  1682.   {
  1683.     fseek(fin,pos,0);
  1684.  
  1685.     len = UTIL_Get_MSB_Long(fin);
  1686.     pos += 4;        /* binary size is 4 bytes */
  1687.     csize = UTIL_Get_MSB_Long(fin);
  1688.     cid   = UTIL_Get_MSB_Long(fin);
  1689.     if (cid == QT_moov)
  1690.     {
  1691.       fseek(fin,pos,0);
  1692.       return(1);
  1693.     }
  1694.     if (len == 0) return(0);
  1695.     pos += len;
  1696.   }
  1697.   return(0);
  1698. }
  1699.  
  1700. #define QT_BLOCK_INC(x,y,imagex) { x += 4; if (x>=imagex) { x=0; y += 4; }}
  1701.  
  1702. #define QT_MIN_MAX_CHECK(x,y,min_x,min_y,max_x,max_y) {    \
  1703.   if (x > max_x) max_x=x; if (y > max_y) max_y=y;    \
  1704.   if (x < min_x) min_x=x; if (y < min_y) min_y=y;  }
  1705.  
  1706. #define QT_RPZA_C1(ip,c,CAST,rinc) { \
  1707.  *ip++=(CAST)c; *ip++ =(CAST)c; *ip++ =(CAST)c; *ip = (CAST)c; ip +=rinc; \
  1708.  *ip++=(CAST)c; *ip++ =(CAST)c; *ip++ =(CAST)c; *ip = (CAST)c; ip +=rinc; \
  1709.  *ip++=(CAST)c; *ip++ =(CAST)c; *ip++ =(CAST)c; *ip = (CAST)c; ip +=rinc; \
  1710.  *ip++=(CAST)c; *ip++ =(CAST)c; *ip++ =(CAST)c; *ip = (CAST)c; }
  1711.  
  1712. #define QT_RPZA_C4(ip,c,mask,CAST); { \
  1713.  *ip++ =(CAST)(c[((mask>>6)&0x03)]); *ip++ =(CAST)(c[((mask>>4)&0x03)]); \
  1714.  *ip++ =(CAST)(c[((mask>>2)&0x03)]); *ip   =(CAST)(c[ (mask & 0x03)]); }
  1715.  
  1716. #define QT_RPZA_C16(ip,c,CAST,rinc) { \
  1717.  *ip++=(CAST)(*c++); *ip++=(CAST)(*c++); \
  1718.  *ip++=(CAST)(*c++); *ip  =(CAST)(*c++); ip +=rinc; \
  1719.  *ip++=(CAST)(*c++); *ip++=(CAST)(*c++); \
  1720.  *ip++=(CAST)(*c++); *ip  =(CAST)(*c++); ip +=rinc; \
  1721.  *ip++=(CAST)(*c++); *ip++=(CAST)(*c++); \
  1722.  *ip++=(CAST)(*c++); *ip  =(CAST)(*c++); ip +=rinc; \
  1723.  *ip++=(CAST)(*c++); *ip++=(CAST)(*c++); \
  1724.  *ip++=(CAST)(*c++); *ip  =(CAST)(*c  ); }
  1725.  
  1726. #define QT_RPZA_rgbC1(ip,r,g,b) { \
  1727.  *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip++=b; \
  1728.  *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip  =b; }
  1729.  
  1730. #define QT_RPZA_rgbC4(ip,r,g,b,mask); { ULONG _idx; \
  1731.  _idx = (mask>>6)&0x03; *ip++ = r[_idx]; *ip++ = g[_idx]; *ip++ = b[_idx]; \
  1732.  _idx = (mask>>4)&0x03; *ip++ = r[_idx]; *ip++ = g[_idx]; *ip++ = b[_idx]; \
  1733.  _idx = (mask>>2)&0x03; *ip++ = r[_idx]; *ip++ = g[_idx]; *ip++ = b[_idx]; \
  1734.  _idx =  mask    &0x03; *ip++ = r[_idx]; *ip++ = g[_idx]; *ip   = b[_idx]; }
  1735.  
  1736. #define QT_RPZA_rgbC16(ip,r,g,b) { \
  1737.  *ip++= *r++; *ip++= *g++; *ip++= *b++; *ip++= *r++; *ip++= *g++; *ip++= *b++; \
  1738.  *ip++= *r++; *ip++= *g++; *ip++= *b++; *ip++= *r++; *ip++= *g++; *ip  = *b++; }
  1739.  
  1740. ULONG
  1741. QT_Decode_RPZA(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  1742.                     xs,ys,xe,ye,special,extra)
  1743. UBYTE *image;           /* Image Buffer. */
  1744. UBYTE *delta;           /* delta data. */
  1745. ULONG dsize;            /* delta size */
  1746. XA_CHDR *tchdr;        /* color map info */
  1747. ULONG *map;             /* used if it's going to be remapped. */
  1748. ULONG map_flag;         /* whether or not to use remap_map info. */
  1749. ULONG imagex,imagey;    /* Size of image buffer. */
  1750. ULONG imaged;           /* Depth of Image. (IFF specific) */
  1751. ULONG *xs,*ys;          /* pos of changed area. */
  1752. ULONG *xe,*ye;          /* size of changed area. */
  1753. ULONG special;          /* Special Info. */
  1754. ULONG extra;        /* extra info needed to decode delta */
  1755. {
  1756.   LONG x,y,len,row_inc, min_x,max_x,min_y,max_y;
  1757.   UBYTE *dptr;
  1758.   ULONG code,changed;
  1759.   XA_CHDR *chdr;
  1760.  
  1761.   if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0;
  1762.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  1763.   max_x = max_y = 0; min_x = imagex; min_y = imagey; changed = 0;
  1764.   dptr = delta;
  1765.   x = y = 0;
  1766.   if (special) row_inc = (3 * imagex) - 11 ;
  1767.   else row_inc = imagex - 3;
  1768.  
  1769.   dptr++;            /* for 0xe1 */
  1770.   len =(*dptr++)<<16; len |= (*dptr++)<< 8; len |= (*dptr++); /* Read Len */
  1771.   if (len != dsize) /* CHECK FOR CORRUPTION - FAIRLY COMMON */
  1772.   {
  1773.     if (xa_verbose==TRUE) 
  1774.     fprintf(stderr,"QT corruption-skipping this frame %lx %lx\n",dsize,len);
  1775.     return(ACT_DLTA_NOP);
  1776.   }
  1777.   len -= 4;                /* read 4 already */
  1778.   while(len > 0)
  1779.   {
  1780.     code = *dptr++; len--;
  1781.  
  1782.     if ( (code >= 0xa0) && (code <= 0xbf) )            /* SINGLE */
  1783.     {
  1784.       ULONG color,skip;
  1785.       changed = 1;
  1786.       color = (*dptr++) << 8; color |= *dptr++; len -= 2;
  1787.       skip = (code-0x9f);
  1788.       if (special)
  1789.       { UBYTE r,g,b;
  1790.         QT_Get_RGBColor(&r,&g,&b,color); 
  1791.         while(skip--)
  1792.         { UBYTE *i_ptr = (UBYTE *)(image + 3 * (y * imagex + x) );
  1793.       QT_RPZA_rgbC1(i_ptr,r,g,b); i_ptr += row_inc;
  1794.       QT_RPZA_rgbC1(i_ptr,r,g,b); i_ptr += row_inc;
  1795.       QT_RPZA_rgbC1(i_ptr,r,g,b); i_ptr += row_inc;
  1796.       QT_RPZA_rgbC1(i_ptr,r,g,b); 
  1797.       QT_MIN_MAX_CHECK(x,y,min_x,min_y,max_x,max_y);
  1798.       QT_BLOCK_INC(x,y,imagex);
  1799.     }
  1800.       }
  1801.       else /* not special */
  1802.       {
  1803.         color = QT_Get_Color(color,map_flag,map,chdr); 
  1804.         while(skip--)
  1805.         {
  1806.           if ( (x11_bytes_pixel==1) || (map_flag == FALSE) )
  1807.           { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  1808.         QT_RPZA_C1(i_ptr,color,UBYTE,row_inc);
  1809.       }
  1810.           else if (x11_bytes_pixel==4)
  1811.           { ULONG *i_ptr = (ULONG *)(image + 4 * (y * imagex + x) );
  1812.         QT_RPZA_C1(i_ptr,color,ULONG,row_inc);
  1813.       }
  1814.           else /* if (x11_bytes_pixel==2) */
  1815.           { USHORT *i_ptr = (USHORT *)(image + 2 * (y * imagex + x) );
  1816.         QT_RPZA_C1(i_ptr,color,USHORT,row_inc);
  1817.       }
  1818.       QT_MIN_MAX_CHECK(x,y,min_x,min_y,max_x,max_y);
  1819.       QT_BLOCK_INC(x,y,imagex);
  1820.         } /* end of skip-- */
  1821.       } /* end not special */
  1822.     }
  1823.     else if ( (code >= 0x80) && (code <= 0x9f) )        /* SKIP */
  1824.     {
  1825.       ULONG skip = (code-0x7f);
  1826.       while(skip--) QT_BLOCK_INC(x,y,imagex);
  1827.     }
  1828.     else if ( (code < 0x80)                 /* FOUR/SIXTEEN */ 
  1829.          || ((code >= 0xc0) && (code <= 0xdf)) )
  1830.     { ULONG cA,cB;
  1831.       changed = 1;
  1832.       /* Get 1st two colors */
  1833.       if (code >= 0xc0) { cA = (*dptr++) << 8; cA |= *dptr++; len -= 2; }
  1834.       else {cA = (code << 8) | *dptr++; len -= 1;}
  1835.       cB = (*dptr++) << 8; cB |= *dptr++; len -= 2;
  1836.  
  1837.       /****** SIXTEEN COLOR *******/
  1838.       if ( (code < 0x80) && ((cB & 0x8000)==0) ) /* 16 color */
  1839.       {
  1840.         ULONG i,d,*clr,c[16];
  1841.         UBYTE r[16],g[16],b[16];
  1842.     if (special)
  1843.     {
  1844.           QT_Get_RGBColor(&r[0],&g[0],&b[0],cA);
  1845.           QT_Get_RGBColor(&r[1],&g[1],&b[1],cB);
  1846.           for(i=2; i<16; i++)
  1847.           {
  1848.             d = (*dptr++) << 8; d |= *dptr++; len -= 2;
  1849.             QT_Get_RGBColor(&r[i],&g[i],&b[i],d);
  1850.           }
  1851.     }
  1852.     else
  1853.     {
  1854.       clr = c;
  1855.           *clr++ = QT_Get_Color(cA,map_flag,map,chdr);
  1856.           *clr++ = QT_Get_Color(cB,map_flag,map,chdr);
  1857.           for(i=2; i<16; i++)
  1858.           {
  1859.             d = (*dptr++) << 8; d |= *dptr++; len -= 2;
  1860.             *clr++ = QT_Get_Color(d,map_flag,map,chdr);
  1861.           }
  1862.     }
  1863.     clr = c;
  1864.     if (special)
  1865.     { UBYTE *i_ptr = (UBYTE *)(image + 3 * (y * imagex + x) );
  1866.       UBYTE *tr,*tg,*tb; tr=r; tg=g; tb=b;
  1867.       QT_RPZA_rgbC16(i_ptr,tr,tg,tb); *i_ptr += row_inc;
  1868.       QT_RPZA_rgbC16(i_ptr,tr,tg,tb); *i_ptr += row_inc;
  1869.       QT_RPZA_rgbC16(i_ptr,tr,tg,tb); *i_ptr += row_inc;
  1870.       QT_RPZA_rgbC16(i_ptr,tr,tg,tb);
  1871.     }
  1872.     else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  1873.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  1874.       QT_RPZA_C16(i_ptr,clr,UBYTE,row_inc);
  1875.     }
  1876.     else if (x11_bytes_pixel==4)
  1877.     { ULONG *i_ptr = (ULONG *)(image + 4 * (y * imagex + x) );
  1878.       QT_RPZA_C16(i_ptr,clr,ULONG,row_inc);
  1879.     }
  1880.     else /* if (x11_bytes_pixel==2) */
  1881.     { USHORT *i_ptr = (USHORT *)(image + 2 * (y * imagex + x) );
  1882.       QT_RPZA_C16(i_ptr,clr,USHORT,row_inc);
  1883.     }
  1884.     QT_MIN_MAX_CHECK(x,y,min_x,min_y,max_x,max_y);
  1885.     QT_BLOCK_INC(x,y,imagex);
  1886.       } /*** END of SIXTEEN COLOR */
  1887.       else                    /****** FOUR COLOR *******/
  1888.       {
  1889.         ULONG m_cnt,msk0,msk1,msk2,msk3,c[4];
  1890.     UBYTE r[4],g[4],b[4];
  1891.  
  1892.         if (code < 0x80) m_cnt = 1; 
  1893.     else m_cnt = code - 0xbf; 
  1894.  
  1895.     if (special) QT_Get_AV_RGBColors(c,r,g,b,cA,cB);
  1896.     else QT_Get_AV_Colors(c,cA,cB,map_flag,map,chdr);
  1897.  
  1898.         while(m_cnt--)
  1899.         {
  1900.       msk0 = *dptr++; msk1 = *dptr++;
  1901.       msk2 = *dptr++; msk3 = *dptr++; len -= 4;
  1902.       if (special)
  1903.       { UBYTE *i_ptr = (UBYTE *)(image + 3 * (y * imagex + x) );
  1904.         QT_RPZA_rgbC4(i_ptr,r,g,b,msk0); *i_ptr += row_inc;
  1905.         QT_RPZA_rgbC4(i_ptr,r,g,b,msk1); *i_ptr += row_inc;
  1906.         QT_RPZA_rgbC4(i_ptr,r,g,b,msk2); *i_ptr += row_inc;
  1907.         QT_RPZA_rgbC4(i_ptr,r,g,b,msk3);
  1908.       }
  1909.       else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  1910.           { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  1911.         QT_RPZA_C4(i_ptr,c,msk0,UBYTE); i_ptr += row_inc;
  1912.         QT_RPZA_C4(i_ptr,c,msk1,UBYTE); i_ptr += row_inc;
  1913.         QT_RPZA_C4(i_ptr,c,msk2,UBYTE); i_ptr += row_inc;
  1914.         QT_RPZA_C4(i_ptr,c,msk3,UBYTE);
  1915.       }
  1916.       else if (x11_bytes_pixel==4)
  1917.       { ULONG *i_ptr = (ULONG *)(image + 4 * (y * imagex + x) );
  1918.         QT_RPZA_C4(i_ptr,c,msk0,ULONG); i_ptr += row_inc;
  1919.         QT_RPZA_C4(i_ptr,c,msk1,ULONG); i_ptr += row_inc;
  1920.         QT_RPZA_C4(i_ptr,c,msk2,ULONG); i_ptr += row_inc;
  1921.         QT_RPZA_C4(i_ptr,c,msk3,ULONG);
  1922.       }
  1923.       else /* if (x11_bytes_pixel==2) */
  1924.       { USHORT *i_ptr = (USHORT *)(image + 2 * (y * imagex + x) );
  1925.         QT_RPZA_C4(i_ptr,c,msk0,USHORT); i_ptr += row_inc;
  1926.         QT_RPZA_C4(i_ptr,c,msk1,USHORT); i_ptr += row_inc;
  1927.         QT_RPZA_C4(i_ptr,c,msk2,USHORT); i_ptr += row_inc;
  1928.         QT_RPZA_C4(i_ptr,c,msk3,USHORT);
  1929.       }
  1930.       QT_MIN_MAX_CHECK(x,y,min_x,min_y,max_x,max_y);
  1931.       QT_BLOCK_INC(x,y,imagex);
  1932.         }  
  1933.       } /*** END of FOUR COLOR *******/
  1934.     } /*** END of 4/16 COLOR BLOCKS ****/
  1935.     else /* UNKNOWN */
  1936.     {
  1937.       fprintf(stderr,"QT RPZA: Unknown %lx\n",code);
  1938.       return(ACT_DLTA_NOP);
  1939.     }
  1940.   }
  1941.   if (xa_optimize_flag == TRUE)
  1942.   {
  1943.     if (changed) { *xs=min_x; *ys=min_y; *xe=max_x + 4; *ye=max_y + 4; }
  1944.     else  { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); }
  1945.   }
  1946.   else { *xs = *ys = 0; *xe = imagex; *ye = imagey; }
  1947.   if (map_flag) return(ACT_DLTA_MAPD);
  1948.   else return(ACT_DLTA_NORM);
  1949. }
  1950.  
  1951. void QT_Get_RGBColor(r,g,b,color)
  1952. UBYTE *r,*g,*b;
  1953. ULONG color;
  1954. { ULONG ra,ga,ba;
  1955.   ra = (color >> 10) & 0x1f;    ra = (ra << 3) | (ra >> 2);
  1956.   ga = (color >>  5) & 0x1f;    ga = (ga << 3) | (ga >> 2);
  1957.   ba =  color & 0x1f;        ba = (ba << 3) | (ba >> 2);
  1958.   *r = ra; *g = ga; *b = ba;
  1959. }
  1960.  
  1961. ULONG QT_Get_Color(color,map_flag,map,chdr)
  1962. ULONG color,map_flag,*map;
  1963. XA_CHDR *chdr;
  1964. {
  1965.   register ULONG clr,ra,ga,ba,ra5,ga5,ba5;
  1966.  
  1967.   ra5 = (color >> 10) & 0x1f;
  1968.   ga5 = (color >>  5) & 0x1f;
  1969.   ba5 =  color & 0x1f;
  1970.   ra = qt_gamma_adj[ra5]; ga = qt_gamma_adj[ga5]; ba = qt_gamma_adj[ba5];
  1971.  
  1972.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,16);
  1973.   else 
  1974.   { 
  1975.     if ((cmap_color_func == 4) && (chdr))
  1976.     { register ULONG cache_i = color & 0x7fff;
  1977.       if (cmap_cache == 0) CMAP_Cache_Init();
  1978.       if (chdr != cmap_cache_chdr)
  1979.       {
  1980.         CMAP_Cache_Clear();
  1981.         cmap_cache_chdr = chdr;
  1982.       }
  1983.       if (cmap_cache[cache_i] == 0xffff)
  1984.       {
  1985.         clr = chdr->coff +
  1986.            CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,16,16,16,TRUE);
  1987.         cmap_cache[cache_i] = (USHORT)clr;
  1988.       }
  1989.       else clr = (ULONG)cmap_cache[cache_i];
  1990.     }
  1991.     else
  1992.     {
  1993.       if (cmap_true_to_332 == TRUE) clr = CMAP_GET_332(ra5,ga5,ba5,CMAP_SCALE5);
  1994.       else              clr = CMAP_GET_GRAY(ra5,ga5,ba5,CMAP_SCALE10);
  1995.       if (map_flag) clr = map[clr];
  1996.     }
  1997.   }
  1998.   return(clr);
  1999. }
  2000.  
  2001. ULONG QT_Get_Color24(r,g,b,map_flag,map,chdr)
  2002. register ULONG r,g,b;
  2003. ULONG map_flag,*map;
  2004. XA_CHDR *chdr;
  2005. {
  2006.   ULONG clr,ra,ga,ba;
  2007.  
  2008.   ra = xa_gamma_adj[r]; ga = xa_gamma_adj[g]; ba = xa_gamma_adj[b];
  2009.  
  2010.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,16);
  2011.   else 
  2012.   { 
  2013.     if ((cmap_color_func == 4) && (chdr))
  2014.     { register ULONG cache_i;
  2015.       if (cmap_cache == 0) CMAP_Cache_Init();
  2016.       if (chdr != cmap_cache_chdr)
  2017.       {
  2018.         CMAP_Cache_Clear();
  2019.         cmap_cache_chdr = chdr;
  2020.       }
  2021.       cache_i  = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3);
  2022.       if (cmap_cache[cache_i] == 0xffff)
  2023.       {
  2024.         clr = chdr->coff +
  2025.            CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,16,16,16,TRUE);
  2026.         cmap_cache[cache_i] = (USHORT)clr;
  2027.       }
  2028.       else clr = (ULONG)cmap_cache[cache_i];
  2029.     }
  2030.     else 
  2031.     { if (cmap_true_to_332 == TRUE) clr = CMAP_GET_332(r,g,b,CMAP_SCALE8);
  2032.       else              clr = CMAP_GET_GRAY(r,g,b,CMAP_SCALE13);
  2033.       if (map_flag) clr = map[clr];
  2034.     }
  2035.   }
  2036.   return(clr);
  2037. }
  2038.  
  2039. void QT_Get_AV_RGBColors(c,r,g,b,cA,cB)
  2040. ULONG *c;
  2041. UBYTE *r,*g,*b;
  2042. ULONG cA,cB;
  2043. { ULONG rA,gA,bA,rB,gB,bB,ra,ga,ba;
  2044. /**color 3 ***/
  2045.   rA = (cA >> 10) & 0x1f;    r[3] = (rA << 3) | (rA >> 2);
  2046.   gA = (cA >>  5) & 0x1f;    g[3] = (gA << 3) | (gA >> 2);
  2047.   bA =  cA & 0x1f;        b[3] = (bA << 3) | (bA >> 2);
  2048. /**color 0 ***/
  2049.   rB = (cB >> 10) & 0x1f;    r[0] = (rB << 3) | (rB >> 2);
  2050.   gB = (cB >>  5) & 0x1f;    g[0] = (gB << 3) | (gB >> 2);
  2051.   bB =  cB & 0x1f;        b[0] = (bB << 3) | (bB >> 2);
  2052. /**color 2 ***/
  2053.   ra = (21*rA + 11*rB) >> 5;    r[2] = (ra << 3) | (ra >> 2);
  2054.   ga = (21*gA + 11*gB) >> 5;    g[2] = (ga << 3) | (ga >> 2);
  2055.   ba = (21*bA + 11*bB) >> 5;    b[2] = (ba << 3) | (ba >> 2);
  2056. /**color 1 ***/
  2057.   ra = (11*rA + 21*rB) >> 5;    r[1] = (ra << 3) | (ra >> 2);
  2058.   ga = (11*gA + 21*gB) >> 5;    g[1] = (ga << 3) | (ga >> 2);
  2059.   ba = (11*bA + 21*bB) >> 5;    b[1] = (ba << 3) | (ba >> 2);
  2060. }
  2061.  
  2062. void QT_Get_AV_Colors(c,cA,cB,map_flag,map,chdr)
  2063. ULONG *c;
  2064. ULONG cA,cB,map_flag,*map;
  2065. XA_CHDR *chdr;
  2066. {
  2067.   ULONG clr,rA,gA,bA,rB,gB,bB,r0,g0,b0,r1,g1,b1;
  2068.   ULONG rA5,gA5,bA5,rB5,gB5,bB5;
  2069.   ULONG r05,g05,b05,r15,g15,b15;
  2070.  
  2071. /*color 3*/
  2072.   rA5 = (cA >> 10) & 0x1f;
  2073.   gA5 = (cA >>  5) & 0x1f;
  2074.   bA5 =  cA & 0x1f;
  2075. /*color 0*/
  2076.   rB5 = (cB >> 10) & 0x1f;
  2077.   gB5 = (cB >>  5) & 0x1f;
  2078.   bB5 =  cB & 0x1f;
  2079. /*color 2*/
  2080.   r05 = (21*rA5 + 11*rB5) >> 5;
  2081.   g05 = (21*gA5 + 11*gB5) >> 5;
  2082.   b05 = (21*bA5 + 11*bB5) >> 5;
  2083. /*color 1*/
  2084.   r15 = (11*rA5 + 21*rB5) >> 5;
  2085.   g15 = (11*gA5 + 21*gB5) >> 5;
  2086.   b15 = (11*bA5 + 21*bB5) >> 5;
  2087. /*adj and scale to 16 bits */
  2088.   rA=qt_gamma_adj[rA5]; gA=qt_gamma_adj[gA5]; bA=qt_gamma_adj[bA5];
  2089.   rB=qt_gamma_adj[rB5]; gB=qt_gamma_adj[gB5]; bB=qt_gamma_adj[bB5];
  2090.   r0=qt_gamma_adj[r05]; g0=qt_gamma_adj[g05]; b0=qt_gamma_adj[b05];
  2091.   r1=qt_gamma_adj[r15]; g1=qt_gamma_adj[g15]; b1=qt_gamma_adj[b15];
  2092.  
  2093.   /*** 1st Color **/
  2094.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(rA,gA,bA,16);
  2095.   else 
  2096.   { 
  2097.     if ((cmap_color_func == 4) && (chdr))
  2098.     { register ULONG cache_i = cA & 0x7fff;
  2099.       if (cmap_cache == 0) CMAP_Cache_Init();
  2100.       if (chdr != cmap_cache_chdr)
  2101.       {
  2102.         CMAP_Cache_Clear();
  2103.         cmap_cache_chdr = chdr;
  2104.       }
  2105.       if (cmap_cache[cache_i] == 0xffff)
  2106.       {
  2107.         clr = chdr->coff +
  2108.            CMAP_Find_Closest(chdr->cmap,chdr->csize,rA,gA,bA,16,16,16,TRUE);
  2109.         cmap_cache[cache_i] = (USHORT)clr;
  2110.       }
  2111.       else clr = (ULONG)cmap_cache[cache_i];
  2112.     }
  2113.     else
  2114.     { if (cmap_true_to_332 == TRUE) clr = CMAP_GET_332(rA5,gA5,bA5,CMAP_SCALE5);
  2115.       else    clr = CMAP_GET_GRAY(rA5,gA5,bA5,CMAP_SCALE10);
  2116.       if (map_flag) clr = map[clr];
  2117.     }
  2118.   }
  2119.   c[3] = clr;
  2120.  
  2121.   /*** 2nd Color **/
  2122.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(rB,gB,bB,16);
  2123.   else 
  2124.   { 
  2125.     if ((cmap_color_func == 4) && (chdr))
  2126.     { register ULONG cache_i = cB & 0x7fff;
  2127.       if (cmap_cache[cache_i] == 0xffff)
  2128.       {
  2129.         clr = chdr->coff +
  2130.            CMAP_Find_Closest(chdr->cmap,chdr->csize,rB,gB,bB,16,16,16,TRUE);
  2131.         cmap_cache[cache_i] = (USHORT)clr;
  2132.       }
  2133.       else clr = (ULONG)cmap_cache[cache_i];
  2134.     }
  2135.     else
  2136.     { if (cmap_true_to_332 == TRUE) clr = CMAP_GET_332(rB5,gB5,bB5,CMAP_SCALE5);
  2137.       else    clr = CMAP_GET_GRAY(rB5,gB5,bB5,CMAP_SCALE10);
  2138.       if (map_flag) clr = map[clr];
  2139.     }
  2140.   }
  2141.   c[0] = clr;
  2142.  
  2143.   /*** 1st Av ****/
  2144.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(r0,g0,b0,16);
  2145.   else 
  2146.   { 
  2147.     if ((cmap_color_func == 4) && (chdr))
  2148.     { register ULONG cache_i;
  2149.       cache_i = (ULONG)(r05 << 10) | (g05 << 5) | b05;
  2150.       if (cmap_cache[cache_i] == 0xffff)
  2151.       {
  2152.         clr = chdr->coff +
  2153.            CMAP_Find_Closest(chdr->cmap,chdr->csize,r0,g0,b0,16,16,16,TRUE);
  2154.         cmap_cache[cache_i] = (USHORT)clr;
  2155.       }
  2156.       else clr = (ULONG)cmap_cache[cache_i];
  2157.     }
  2158.     else
  2159.     { if (cmap_true_to_332 == TRUE) clr = CMAP_GET_332(r05,g05,b05,CMAP_SCALE5);
  2160.       else    clr = CMAP_GET_GRAY(r05,g05,b05,CMAP_SCALE10);
  2161.       if (map_flag) clr = map[clr];
  2162.     }
  2163.   }
  2164.   c[2] = clr;
  2165.  
  2166.   /*** 2nd Av ****/
  2167.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(r1,g1,b1,16);
  2168.   else 
  2169.   { 
  2170.     if ((cmap_color_func == 4) && (chdr))
  2171.     { register ULONG cache_i;
  2172.       cache_i = (ULONG)(r15 << 10) | (g15 << 5) | b15;
  2173.       if (cmap_cache[cache_i] == 0xffff)
  2174.       {
  2175.         clr = chdr->coff +
  2176.            CMAP_Find_Closest(chdr->cmap,chdr->csize,r1,g1,b1,16,16,16,TRUE);
  2177.         cmap_cache[cache_i] = (USHORT)clr;
  2178.       }
  2179.       else clr = (ULONG)cmap_cache[cache_i];
  2180.     }
  2181.     else
  2182.     { if (cmap_true_to_332 == TRUE) clr = CMAP_GET_332(r15,g15,b15,CMAP_SCALE5);
  2183.       else    clr = CMAP_GET_GRAY(r15,g15,b15,CMAP_SCALE10);
  2184.       if (map_flag) clr = map[clr];
  2185.     }
  2186.   }
  2187.   c[1] = clr;
  2188. }
  2189.  
  2190.  
  2191. ULONG
  2192. QT_Decode_RLE16(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  2193.                     xs,ys,xe,ye,special,extra)
  2194. UBYTE *image;           /* Image Buffer. */
  2195. UBYTE *delta;           /* delta data. */
  2196. ULONG dsize;            /* delta size */
  2197. XA_CHDR *tchdr;        /* color map info */
  2198. ULONG *map;             /* used if it's going to be remapped. */
  2199. ULONG map_flag;         /* whether or not to use remap_map info. */
  2200. ULONG imagex,imagey;    /* Size of image buffer. */
  2201. ULONG imaged;           /* Depth of Image. (IFF specific) */
  2202. ULONG *xs,*ys;          /* pos of changed area. */
  2203. ULONG *xe,*ye;          /* size of changed area. */
  2204. ULONG special;          /* Special Info. */
  2205. ULONG extra;        /* extra info needed to decode delta */
  2206. {
  2207.   LONG y,d,lines; /* LONG min_x,max_x,min_y,max_y; */
  2208.   ULONG special_flag;
  2209.   UBYTE r,g,b,*dptr;
  2210.   XA_CHDR *chdr;
  2211.  
  2212.   if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0;
  2213.  
  2214.   special_flag = special & 0x0001;
  2215.  
  2216.   dptr = delta;
  2217.   dptr += 4;    /* skip codec size */
  2218.   d = (*dptr++) << 8;  d |= *dptr++;   /* read code either 0008 or 0000 */
  2219.   if (d == 0x0000) /* NOP */
  2220.   { /* There is one more byte 0x00 that I don't read in this case */
  2221.     *xs = *ys = *xe = *ye = 0;
  2222.     return(ACT_DLTA_NOP);
  2223.   }
  2224.   y = (*dptr++) << 8; y |= *dptr++;        /* start line */
  2225.   dptr += 2;                    /* unknown */
  2226.   lines = (*dptr++) << 8; lines |= *dptr++;    /* number of lines */
  2227.   dptr += 2;                    /* unknown */
  2228.   while(lines--)                /* loop thru lines */
  2229.   {
  2230.     ULONG d,xskip,cnt;
  2231.     xskip = *dptr++;                /* skip x pixels */
  2232.     cnt = *dptr++;                /* RLE code */
  2233.  
  2234.     if (special_flag)
  2235.     { UBYTE *iptr = (UBYTE *)(image + 3*((y * imagex) + (xskip-1)) );
  2236.       while(cnt != 0xff)                /* while not EOL */
  2237.       {
  2238.         if (cnt == 0x00) { xskip = *dptr++; iptr += 3*(xskip-1); }
  2239.         else if (cnt < 0x80)                /* run of data */
  2240.           while(cnt--) { d = (*dptr++ << 8); d |= *dptr++;
  2241.              QT_Get_RGBColor(&r,&g,&b,d);
  2242.             *iptr++ = r; *iptr++ = g; *iptr++ = b; }
  2243.         else                        /* repeat data */
  2244.         { cnt = 0x100 - cnt; d = (*dptr++ << 8); d |= *dptr++;
  2245.           QT_Get_RGBColor(&r,&g,&b,d);
  2246.           while(cnt--) { *iptr++ = r; *iptr++ = g; *iptr++ = b; }
  2247.         }
  2248.         cnt = *dptr++;                /* get new RLE code */
  2249.       } /* end of line */
  2250.     }
  2251.     else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2252.     { UBYTE *iptr = (UBYTE *)(image + (y * imagex) + (xskip-1) );
  2253.       while(cnt != 0xff)                /* while not EOL */
  2254.       {
  2255.         if (cnt == 0x00) { xskip = *dptr++; iptr += (xskip-1); }
  2256.         else if (cnt < 0x80)                /* run of data */
  2257.           while(cnt--) { d = (*dptr++ << 8); d |= *dptr++;
  2258.         *iptr++ = (UBYTE)QT_Get_Color(d,map_flag,map,chdr); }
  2259.         else                        /* repeat data */
  2260.         { cnt = 0x100 - cnt; d = (*dptr++ << 8); d |= *dptr++;
  2261.           d = QT_Get_Color(d,map_flag,map,chdr);
  2262.           while(cnt--) { *iptr++ = (UBYTE)d; }
  2263.         }
  2264.         cnt = *dptr++;                /* get new RLE code */
  2265.       } /* end of line */
  2266.     }
  2267.     else if (x11_bytes_pixel==4)
  2268.     { ULONG *iptr = (ULONG *)(image + 4*((y * imagex)+(xskip-1)) );
  2269.       while(cnt != 0xff)                /* while not EOL */
  2270.       {
  2271.         if (cnt == 0x00) { xskip = *dptr++; iptr += (xskip-1); }
  2272.         else if (cnt < 0x80)                /* run of data */
  2273.           while(cnt--) { d = (*dptr++ << 8); d |= *dptr++;
  2274.         *iptr++ = (ULONG)QT_Get_Color(d,map_flag,map,chdr); }
  2275.         else                        /* repeat data */
  2276.         { cnt = 0x100 - cnt; d = (*dptr++ << 8); d |= *dptr++;
  2277.           d = QT_Get_Color(d,map_flag,map,chdr);
  2278.           while(cnt--) { *iptr++ = (ULONG)d; }
  2279.         }
  2280.         cnt = *dptr++;                /* get new RLE code */
  2281.       } /* end of line */
  2282.     }
  2283.     else /* if (x11_bytes_pixel==2) */
  2284.     { USHORT *iptr = (USHORT *)(image + 2*((y * imagex)+(xskip-1)) );
  2285.       while(cnt != 0xff)                /* while not EOL */
  2286.       {
  2287.         if (cnt == 0x00) { xskip = *dptr++; iptr += (xskip-1); }
  2288.         else if (cnt < 0x80)                /* run of data */
  2289.           while(cnt--) { d = (*dptr++ << 8); d |= *dptr++;
  2290.         *iptr++ = (USHORT)QT_Get_Color(d,map_flag,map,chdr); }
  2291.         else                        /* repeat data */
  2292.         { cnt = 0x100 - cnt; d = (*dptr++ << 8); d |= *dptr++;
  2293.           d = QT_Get_Color(d,map_flag,map,chdr);
  2294.           while(cnt--) { *iptr++ = (USHORT)d; }
  2295.         }
  2296.         cnt = *dptr++;                /* get new RLE code */
  2297.       } /* end of line */
  2298.     }
  2299.     y++;
  2300.   } /* end of lines */
  2301.  /* one more zero byte */
  2302.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  2303.  if (map_flag==TRUE) return(ACT_DLTA_MAPD);
  2304.  else return(ACT_DLTA_NORM);
  2305. }
  2306.  
  2307.  
  2308. ULONG
  2309. QT_Decode_RLE33(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  2310.                     xs,ys,xe,ye,special,extra)
  2311. UBYTE *image;           /* Image Buffer. */
  2312. UBYTE *delta;           /* delta data. */
  2313. ULONG dsize;            /* delta size */
  2314. XA_CHDR *tchdr;        /* color map info */
  2315. ULONG *map;             /* used if it's going to be remapped. */
  2316. ULONG map_flag;         /* whether or not to use remap_map info. */
  2317. ULONG imagex,imagey;    /* Size of image buffer. */
  2318. ULONG imaged;           /* Depth of Image. (IFF specific) */
  2319. ULONG *xs,*ys;          /* pos of changed area. */
  2320. ULONG *xe,*ye;          /* size of changed area. */
  2321. ULONG special;          /* Special Info. */
  2322. ULONG extra;        /* extra info needed to decode delta */
  2323. {
  2324.   LONG x,y,d,lines; /* LONG min_x,max_x,min_y,max_y; */
  2325.   UBYTE *dptr;
  2326.  
  2327.   dptr = delta;
  2328.   dptr += 4;    /* skip codec size */
  2329.   d = (*dptr++) << 8;  d |= *dptr++;   /* read code either 0008 or 0000 */
  2330.   if (d == 0x0000) /* NOP */
  2331.   { /* There is one more byte 0x00 that I don't read in this case */
  2332.     *xs = *ys = *xe = *ye = 0;
  2333.     return(ACT_DLTA_NOP);
  2334.   }
  2335.   y = (*dptr++) << 8; y |= *dptr++;        /* start line */
  2336.   dptr += 2;                    /* unknown */
  2337.   lines = (*dptr++) << 8; lines |= *dptr++;    /* number of lines */
  2338.   dptr += 2;                    /* unknown */
  2339.   x = 0; y--; lines++;
  2340.   while(lines)                /* loop thru lines */
  2341.   {
  2342.     ULONG d,xskip,cnt;
  2343.     xskip = *dptr++;                /* skip x pixels */
  2344.     cnt = *dptr++;                /* RLE code */
  2345.     
  2346.     if ((xskip == 0x80) && (cnt == 0x00))  /* end of codec */
  2347.     {lines = 0; y++; x = 0; }
  2348.     else if ((xskip == 0x80) && (cnt == 0xff)) /* skip line */
  2349.     {lines--; y++; x = 0; }
  2350.     else
  2351.     {
  2352.       if (xskip & 0x80) {lines--; y++; x = xskip & 0x7f;}
  2353.       else x += xskip;
  2354.  
  2355.       if (cnt < 0x80)                /* run of data */
  2356.       { 
  2357.         UBYTE *bptr; USHORT *sptr; ULONG *lptr;
  2358.     if ((x11_bytes_pixel==1) || (map_flag==FALSE) )
  2359.         bptr = (UBYTE *)(image + (y * imagex) + (x << 4) );
  2360.     else if (x11_bytes_pixel==2)
  2361.         sptr = (USHORT *)(image + 2*(y * imagex) + (x << 5) );
  2362.         else lptr = (ULONG *)(image + 4*(y * imagex) + (x << 6) );
  2363.         x += cnt;
  2364.         while(cnt--) 
  2365.         { ULONG i,mask;
  2366.           d = (*dptr++ << 8); d |= *dptr++;
  2367.           mask = 0x8000;
  2368.           for(i=0;i<16;i++)
  2369.           {
  2370.             if (map_flag==FALSE) 
  2371.         { if (d & mask) *bptr++ = 0;  else *bptr++ = 1; }
  2372.             else if (x11_bytes_pixel==1) {if (d & mask) *bptr++=(UBYTE)map[0];
  2373.                     else *bptr++=(UBYTE)map[1];}
  2374.             else if (x11_bytes_pixel==2) {if (d & mask) *sptr++ =(USHORT)map[0];
  2375.                     else *sptr++ =(USHORT)map[1]; }
  2376.             else { if (d & mask) *lptr++ = (ULONG)map[0]; 
  2377.                     else *lptr++ = (ULONG)map[1]; }
  2378.             mask >>= 1;
  2379.           }
  2380.         }
  2381.       } /* end run */ 
  2382.       else                /* repeat data */
  2383.       { 
  2384.         UBYTE *bptr; USHORT *sptr; ULONG *lptr;
  2385.     if ((x11_bytes_pixel==1) || (map_flag==FALSE) )
  2386.         bptr = (UBYTE *)(image + (y * imagex) + (x << 4) );
  2387.     else if (x11_bytes_pixel==2)
  2388.         sptr = (USHORT *)(image + 2*(y * imagex) + (x << 5) );
  2389.         else lptr = (ULONG *)(image + 4*(y * imagex) + (x << 6) );
  2390.         cnt = 0x100 - cnt;
  2391.         x += cnt;
  2392.         d = (*dptr++ << 8); d |= *dptr++;
  2393.         while(cnt--) 
  2394.         { ULONG i,mask;
  2395.           mask = 0x8000;
  2396.           for(i=0;i<16;i++)
  2397.           {
  2398.             if (map_flag==FALSE) 
  2399.         { if (d & mask) *bptr++ = 0;  else *bptr++ = 1; }
  2400.             else if (x11_bytes_pixel==1) {if (d & mask) *bptr++=(UBYTE)map[0];
  2401.                     else *bptr++=(UBYTE)map[1];}
  2402.             else if (x11_bytes_pixel==2) {if (d & mask) *sptr++ =(USHORT)map[0];
  2403.                     else *sptr++ =(USHORT)map[1]; }
  2404.             else { if (d & mask) *lptr++ = (ULONG)map[0]; 
  2405.                     else *lptr++ = (ULONG)map[1]; }
  2406.             mask >>= 1;
  2407.           }
  2408.         }
  2409.       } /* end repeat */
  2410.     } /* end of code */
  2411.   } /* end of lines */
  2412.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  2413.  if (map_flag==TRUE) return(ACT_DLTA_MAPD);
  2414.  else return(ACT_DLTA_NORM);
  2415. }
  2416.  
  2417. ULONG
  2418. QT_Decode_RAW(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  2419.                     xs,ys,xe,ye,special,extra)
  2420. UBYTE *image;           /* Image Buffer. */
  2421. UBYTE *delta;           /* delta data. */
  2422. ULONG dsize;            /* delta size */
  2423. XA_CHDR *tchdr;        /* color map info */
  2424. ULONG *map;             /* used if it's going to be remapped. */
  2425. ULONG map_flag;         /* whether or not to use remap_map info. */
  2426. ULONG imagex,imagey;    /* Size of image buffer. */
  2427. ULONG imaged;           /* Depth of Image. (IFF specific) */
  2428. ULONG *xs,*ys;          /* pos of changed area. */
  2429. ULONG *xe,*ye;          /* size of changed area. */
  2430. ULONG special;          /* Special Info. */
  2431. ULONG extra;        /* extra info needed to decode delta */
  2432. {
  2433.   UBYTE *dptr = delta;
  2434.   LONG i = imagex * imagey;
  2435.   
  2436.   if (map_flag==FALSE) { UBYTE *iptr = (UBYTE *)image; 
  2437.                 while(i--) *iptr++ = (UBYTE)*dptr++; }
  2438.   else if (x11_bytes_pixel==1) { UBYTE *iptr = (UBYTE *)image; 
  2439.                 while(i--) *iptr++ = (UBYTE)map[*dptr++]; }
  2440.   else if (x11_bytes_pixel==2) { USHORT *iptr = (USHORT *)image; 
  2441.                 while(i--) *iptr++ = (USHORT)map[*dptr++]; }
  2442.   else { ULONG *iptr = (ULONG *)image; 
  2443.                 while(i--) *iptr++ = (ULONG)map[*dptr++]; }
  2444.  
  2445.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  2446.   if (map_flag==TRUE) return(ACT_DLTA_MAPD);
  2447.   else return(ACT_DLTA_NORM);
  2448. }
  2449.  
  2450.  
  2451. #define QT_SMC_O2I(i,o,rinc) { \
  2452. *i++ = *o++; *i++ = *o++; *i++ = *o++; *i++ = *o++; i += rinc; o += rinc; \
  2453. *i++ = *o++; *i++ = *o++; *i++ = *o++; *i++ = *o++; i += rinc; o += rinc; \
  2454. *i++ = *o++; *i++ = *o++; *i++ = *o++; *i++ = *o++; i += rinc; o += rinc; \
  2455. *i++ = *o++; *i++ = *o++; *i++ = *o++; *i++ = *o++;  } 
  2456.  
  2457. #define QT_SMC_C1(i,c,rinc) { \
  2458. *i++ = c; *i++ = c; *i++ = c; *i++ = c;  i += rinc; \
  2459. *i++ = c; *i++ = c; *i++ = c; *i++ = c;  i += rinc; \
  2460. *i++ = c; *i++ = c; *i++ = c; *i++ = c;  i += rinc; \
  2461. *i++ = c; *i++ = c; *i++ = c; *i++ = c;  i += rinc; }
  2462.  
  2463. #define QT_SMC_C2(i,c0,c1,msk,rinc) { \
  2464. *i++ =(msk&0x80)?c1:c0; *i++ =(msk&0x40)?c1:c0; \
  2465. *i++ =(msk&0x20)?c1:c0; *i++ =(msk&0x10)?c1:c0; i += rinc; \
  2466. *i++ =(msk&0x08)?c1:c0; *i++ =(msk&0x04)?c1:c0; \
  2467. *i++ =(msk&0x02)?c1:c0; *i++ =(msk&0x01)?c1:c0; }
  2468.  
  2469. #define QT_SMC_C4(i,CST,c,mska,mskb,rinc) { \
  2470. *i++ = (CST)(c[(mska>>6) & 0x03]); *i++ = (CST)(c[(mska>>4) & 0x03]); \
  2471. *i++ = (CST)(c[(mska>>2) & 0x03]); *i++ = (CST)(c[mska & 0x03]); i+=rinc; \
  2472. *i++ = (CST)(c[(mskb>>6) & 0x03]); *i++ = (CST)(c[(mskb>>4) & 0x03]); \
  2473. *i++ = (CST)(c[(mskb>>2) & 0x03]); *i++ = (CST)(c[mskb & 0x03]); }
  2474.  
  2475. #define QT_SMC_C8(i,CST,c,msk,rinc) { \
  2476. *i++ = (CST)(c[(msk>>21) & 0x07]); *i++ = (CST)(c[(msk>>18) & 0x07]); \
  2477. *i++ = (CST)(c[(msk>>15) & 0x07]); *i++ = (CST)(c[(msk>>12) & 0x07]); i+=rinc; \
  2478. *i++ = (CST)(c[(msk>> 9) & 0x07]); *i++ = (CST)(c[(msk>> 6) & 0x07]); \
  2479. *i++ = (CST)(c[(msk>> 3) & 0x07]); *i++ = (CST)(c[msk & 0x07]); }
  2480.  
  2481. #define QT_SMC_C16m(i,dp,CST,map,rinc) { \
  2482. *i++ =(CST)map[*dp++]; *i++ =(CST)map[*dp++]; \
  2483. *i++ =(CST)map[*dp++]; *i++ =(CST)map[*dp++]; i += rinc; \
  2484. *i++ =(CST)map[*dp++]; *i++ =(CST)map[*dp++]; \
  2485. *i++ =(CST)map[*dp++]; *i++ =(CST)map[*dp++]; }
  2486.  
  2487. #define QT_SMC_C16(i,dp,CST) { \
  2488. *i++ =(CST)(*dp++); *i++ =(CST)(*dp++); \
  2489. *i++ =(CST)(*dp++); *i++ =(CST)(*dp++); }
  2490.  
  2491. ULONG
  2492. QT_Decode_SMC(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  2493.                     xs,ys,xe,ye,special,extra)
  2494. UBYTE *image;           /* Image Buffer. */
  2495. UBYTE *delta;           /* delta data. */
  2496. ULONG dsize;            /* delta size */
  2497. XA_CHDR *tchdr;        /* color map info */
  2498. ULONG *map;             /* used if it's going to be remapped. */
  2499. ULONG map_flag;         /* whether or not to use remap_map info. */
  2500. ULONG imagex,imagey;    /* Size of image buffer. */
  2501. ULONG imaged;           /* Depth of Image. (IFF specific) */
  2502. ULONG *xs,*ys;          /* pos of changed area. */
  2503. ULONG *xe,*ye;          /* size of changed area. */
  2504. ULONG special;          /* Special Info. */
  2505. ULONG extra;        /* extra info needed to decode delta */
  2506. {
  2507.   LONG x,y,len,row_inc; /* LONG min_x,max_x,min_y,max_y; */
  2508.   UBYTE *dptr;
  2509.   ULONG i,cnt,hicode,code;
  2510.   ULONG *c;
  2511.  
  2512.   smc_8cnt = smc_Acnt = smc_Ccnt = 0;
  2513.  
  2514.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  2515.   dptr = delta;
  2516.   x = y = 0;
  2517.   row_inc = imagex - 4;
  2518.  
  2519.   dptr++;                /* skip over 0xe1 */
  2520.   len =(*dptr++)<<16; len |= (*dptr++)<< 8; len |= (*dptr++); /* Read Len */
  2521.   len -= 4;                /* read 4 already */
  2522.   while(len > 0)
  2523.   {
  2524.     code = *dptr++; len--; hicode = code & 0xf0;
  2525.     switch(hicode)
  2526.     {
  2527.       case 0x00: /* SKIPs */
  2528.       case 0x10:
  2529.     if (hicode == 0x10) {cnt = 1 + *dptr++; len -= 1;}
  2530.     else cnt = 1 + (code & 0x0f);
  2531.         while(cnt--) {x += 4; if (x >= imagex) { x = 0; y += 4; } }
  2532.     break;
  2533.       case 0x20: /* Repeat Last Block */
  2534.       case 0x30:
  2535.     { LONG tx,ty;
  2536.       if (hicode == 0x30) {cnt = 1 + *dptr++; len--;}
  2537.       else cnt = 1 + (code & 0x0f);
  2538.       if (x==0) {ty = y-4; tx = imagex-4;} else {ty=y; tx = x-4;}
  2539.  
  2540.       while(cnt--)
  2541.       { 
  2542.         if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2543.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2544.           UBYTE *o_ptr = (UBYTE *)(image + ty * imagex + tx);
  2545.           QT_SMC_O2I(i_ptr,o_ptr,row_inc);
  2546.         } else if (x11_bytes_pixel==2)
  2547.         { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x) );
  2548.           USHORT *o_ptr = (USHORT *)(image + 2*(ty * imagex + tx) );
  2549.           QT_SMC_O2I(i_ptr,o_ptr,row_inc);
  2550.         } else /* if (x11_bytes_pixel==4) */
  2551.         { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x) );
  2552.           ULONG *o_ptr = (ULONG *)(image + 4*(ty * imagex + tx) );
  2553.           QT_SMC_O2I(i_ptr,o_ptr,row_inc);
  2554.         }
  2555.         x += 4; if (x >= imagex) { x = 0; y += 4; }
  2556.       }
  2557.     }
  2558.     break;
  2559.       case 0x40: /* */
  2560.       case 0x50:
  2561.     { ULONG cnt,cnt1;
  2562.       ULONG m_cnt,m_cnt1;
  2563.       LONG m_tx,m_ty;
  2564.           LONG tx,ty;
  2565.       if (hicode == 0x50) 
  2566.       {  
  2567.          m_cnt1 = 1 + *dptr++; len--; 
  2568.          m_cnt = 2;
  2569.       }
  2570.           else 
  2571.       {
  2572.         m_cnt1 = (1 + (code & 0x0f));
  2573.         m_cnt = 2;
  2574.       }
  2575.           m_tx = x-(LONG)(4 * m_cnt); m_ty = y; 
  2576.       if (m_tx < 0) {m_tx += imagex; m_ty -= 4;}
  2577.       cnt1 = m_cnt1;
  2578.       while(cnt1--)
  2579.       {
  2580.         cnt = m_cnt; tx = m_tx; ty = m_ty;
  2581.         while(cnt--)
  2582.         { 
  2583.           if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2584.           { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2585.         UBYTE *o_ptr = (UBYTE *)(image + ty * imagex + tx);
  2586.         QT_SMC_O2I(i_ptr,o_ptr,row_inc);
  2587.           } else if (x11_bytes_pixel==2)
  2588.           { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x));
  2589.         USHORT *o_ptr = (USHORT *)(image + 2*(ty * imagex + tx));
  2590.         QT_SMC_O2I(i_ptr,o_ptr,row_inc);
  2591.           } else 
  2592.           { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x));
  2593.         ULONG *o_ptr = (ULONG *)(image + 4*(ty * imagex + tx));
  2594.         QT_SMC_O2I(i_ptr,o_ptr,row_inc);
  2595.           }
  2596.           x += 4; if (x >= imagex) { x = 0; y += 4; }
  2597.           tx += 4; if (tx >= imagex) { tx = 0; ty += 4; }
  2598.         } /* end of cnt */
  2599.       } /* end of cnt1 */
  2600.     }
  2601.     break;
  2602.  
  2603.       case 0x60: /* Repeat Data */
  2604.       case 0x70:
  2605.     { ULONG ct,cnt;
  2606.       if (hicode == 0x70) {cnt = 1 + *dptr++; len--;}
  2607.       else cnt = 1 + (code & 0x0f);
  2608.       ct = (map_flag)?(map[*dptr++]):(ULONG)(*dptr++); len--;
  2609.       while(cnt--)
  2610.       {
  2611.         if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2612.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2613.           UBYTE d = (UBYTE)(ct);
  2614.           QT_SMC_C1(i_ptr,d,row_inc);
  2615.         } else if (x11_bytes_pixel==2)
  2616.         { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x));
  2617.           USHORT d = (UBYTE)(ct);
  2618.           QT_SMC_C1(i_ptr,d,row_inc);
  2619.         } else
  2620.         { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x));
  2621.           QT_SMC_C1(i_ptr,ct,row_inc);
  2622.         }
  2623.         x += 4; if (x >= imagex) { x = 0; y += 4; }
  2624.       }
  2625.     }
  2626.     break;
  2627.  
  2628.       case 0x80: /* 2 colors plus 16 mbits per */
  2629.       case 0x90:
  2630.         { ULONG cnt = 1 + (code & 0x0f);
  2631.       if (hicode == 0x80)
  2632.       {
  2633.             c = (ULONG *)&smc_8[ (smc_8cnt * 2) ];  len -= 2;
  2634.         smc_8cnt++; if (smc_8cnt >= SMC_MAX_CNT) smc_8cnt -= SMC_MAX_CNT;
  2635.         for(i=0;i<2;i++) {c[i]=(map_flag)?map[*dptr++]:(ULONG)(*dptr++);}
  2636.       }
  2637.           else { c = (ULONG *)&smc_8[ ((ULONG)(*dptr++) << 1) ]; len--; }
  2638.       while(cnt--)
  2639.       { ULONG msk1,msk0;
  2640.         msk0 = *dptr++; msk1 = *dptr++;  len-= 2;
  2641.         if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2642.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2643.           UBYTE c0=(UBYTE)c[0];    UBYTE c1=(UBYTE)c[1];
  2644.           QT_SMC_C2(i_ptr,c0,c1,msk0,row_inc); i_ptr += row_inc;
  2645.           QT_SMC_C2(i_ptr,c0,c1,msk1,row_inc);
  2646.         } else if (x11_bytes_pixel==2)
  2647.         { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x));
  2648.           USHORT c0=(USHORT)c[0];    USHORT c1=(USHORT)c[1];
  2649.           QT_SMC_C2(i_ptr,c0,c1,msk0,row_inc); i_ptr += row_inc;
  2650.           QT_SMC_C2(i_ptr,c0,c1,msk1,row_inc);
  2651.         } else
  2652.         { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x));
  2653.           ULONG c0=(ULONG)c[0];    ULONG c1=(ULONG)c[1];
  2654.           QT_SMC_C2(i_ptr,c0,c1,msk0,row_inc); i_ptr += row_inc;
  2655.           QT_SMC_C2(i_ptr,c0,c1,msk1,row_inc);
  2656.         }
  2657.         x += 4; if (x >= imagex) { x = 0; y += 4; }
  2658.           } 
  2659.         } 
  2660.     break;
  2661.  
  2662.       case 0xA0: /* 4 color + 32 mbits */
  2663.       case 0xB0:
  2664.         { ULONG cnt = 1 + (code & 0xf);
  2665.           if (hicode == 0xA0)
  2666.           {
  2667.             c = (ULONG *)&smc_A[ (smc_Acnt << 2) ]; len -= 4;
  2668.             smc_Acnt++; if (smc_Acnt >= SMC_MAX_CNT) smc_Acnt -= SMC_MAX_CNT;
  2669.             for(i=0;i<4;i++) {c[i]=(map_flag)?map[*dptr++]:(ULONG)(*dptr++);}
  2670.           }
  2671.           else { c = (ULONG *)&smc_A[ ((ULONG)(*dptr++) << 2) ]; len--; }
  2672.       while(cnt--)
  2673.       { UBYTE msk0,msk1,msk2,msk3; 
  2674.         msk0 = *dptr++;    msk1 = *dptr++; 
  2675.         msk2 = *dptr++;    msk3 = *dptr++;        len -= 4;
  2676.         if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2677.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2678.           QT_SMC_C4(i_ptr,UBYTE,c,msk0,msk1,row_inc); i_ptr += row_inc;
  2679.           QT_SMC_C4(i_ptr,UBYTE,c,msk2,msk3,row_inc);
  2680.         } else if (x11_bytes_pixel==2)
  2681.         { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x));
  2682.           QT_SMC_C4(i_ptr,USHORT,c,msk0,msk1,row_inc); i_ptr += row_inc;
  2683.           QT_SMC_C4(i_ptr,USHORT,c,msk2,msk3,row_inc);
  2684.         } else
  2685.         { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x));
  2686.           QT_SMC_C4(i_ptr,ULONG,c,msk0,msk1,row_inc); i_ptr += row_inc;
  2687.           QT_SMC_C4(i_ptr,ULONG,c,msk2,msk3,row_inc);
  2688.         }
  2689.         x += 4; if (x >= imagex) { x = 0; y += 4; }
  2690.           } 
  2691.         } 
  2692.     break;
  2693.  
  2694.       case 0xC0: /* 8 colors + 48 mbits */
  2695.       case 0xD0:
  2696.         { ULONG cnt = 1 + (code & 0xf);
  2697.           if (hicode == 0xC0)
  2698.           {
  2699.             c = (ULONG *)&smc_C[ (smc_Ccnt << 3) ];   len -= 8;
  2700.             smc_Ccnt++; if (smc_Ccnt >= SMC_MAX_CNT) smc_Ccnt -= SMC_MAX_CNT;
  2701.             for(i=0;i<8;i++) {c[i]=(map_flag)?map[*dptr++]:(ULONG)(*dptr++);}
  2702.           }
  2703.           else { c = (ULONG *)&smc_C[ ((ULONG)(*dptr++) << 3) ]; len--; }
  2704.  
  2705.       while(cnt--)
  2706.       { ULONG t,mbits0,mbits1;
  2707.         t = (*dptr++) << 8; t |= *dptr++;
  2708.         mbits0  = (t & 0xfff0) << 8;  mbits1  = (t & 0x000f) << 8;
  2709.         t = (*dptr++) << 8; t |= *dptr++;
  2710.         mbits0 |= (t & 0xfff0) >> 4;  mbits1 |= (t & 0x000f) << 4;
  2711.         t = (*dptr++) << 8; t |= *dptr++;
  2712.         mbits1 |= (t & 0xfff0) << 8;  mbits1 |= (t & 0x000f);
  2713.         len -= 6;
  2714.         if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2715.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2716.           QT_SMC_C8(i_ptr,UBYTE,c,mbits0,row_inc); i_ptr += row_inc;
  2717.           QT_SMC_C8(i_ptr,UBYTE,c,mbits1,row_inc);
  2718.         } else if (x11_bytes_pixel==2)
  2719.         { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x));
  2720.           QT_SMC_C8(i_ptr,USHORT,c,mbits0,row_inc); i_ptr += row_inc;
  2721.           QT_SMC_C8(i_ptr,USHORT,c,mbits1,row_inc);
  2722.         } else
  2723.         { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x));
  2724.           QT_SMC_C8(i_ptr,ULONG,c,mbits0,row_inc); i_ptr += row_inc;
  2725.           QT_SMC_C8(i_ptr,ULONG,c,mbits1,row_inc);
  2726.         }
  2727.         x += 4; if (x >= imagex) { x = 0; y += 4; }
  2728.           } 
  2729.         } 
  2730.     break;
  2731.  
  2732.       case 0xE0: /* 16 colors */
  2733.         { ULONG cnt = 1 + (code & 0x0f);
  2734.       while(cnt--)
  2735.       { 
  2736.         if (map_flag==FALSE)
  2737.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2738.           QT_SMC_C16(i_ptr,dptr,UBYTE); i_ptr += row_inc;
  2739.           QT_SMC_C16(i_ptr,dptr,UBYTE); i_ptr += row_inc;
  2740.           QT_SMC_C16(i_ptr,dptr,UBYTE); i_ptr += row_inc;
  2741.           QT_SMC_C16(i_ptr,dptr,UBYTE);
  2742.         } else if (x11_bytes_pixel==1)
  2743.         { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  2744.           QT_SMC_C16m(i_ptr,dptr,UBYTE,map,row_inc); i_ptr += row_inc;
  2745.           QT_SMC_C16m(i_ptr,dptr,UBYTE,map,row_inc);
  2746.         } else if (x11_bytes_pixel==2)
  2747.         { USHORT *i_ptr = (USHORT *)(image + 2*(y * imagex + x));
  2748.           QT_SMC_C16m(i_ptr,dptr,USHORT,map,row_inc); i_ptr += row_inc;
  2749.           QT_SMC_C16m(i_ptr,dptr,USHORT,map,row_inc);
  2750.         } else
  2751.         { ULONG *i_ptr = (ULONG *)(image + 4*(y * imagex + x));
  2752.           QT_SMC_C16m(i_ptr,dptr,ULONG,map,row_inc); i_ptr += row_inc;
  2753.           QT_SMC_C16m(i_ptr,dptr,ULONG,map,row_inc);
  2754.         }
  2755.         len -= 16; x += 4; if (x >= imagex) { x = 0; y += 4; }
  2756.       }
  2757.     }
  2758.     break;
  2759.  
  2760.       case 0xF0: /* ??? */
  2761.     fprintf(stderr,"SMC opcode %lx is unknown\n",code);
  2762.     TheEnd();
  2763.     break;
  2764.     }
  2765.   }
  2766.   if (map_flag) return(ACT_DLTA_MAPD);
  2767.   else return(ACT_DLTA_NORM);
  2768. }
  2769.  
  2770. ULONG
  2771. QT_Decode_RLE24(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  2772.                     xs,ys,xe,ye,special,extra)
  2773. UBYTE *image;           /* Image Buffer. */
  2774. UBYTE *delta;           /* delta data. */
  2775. ULONG dsize;            /* delta size */
  2776. XA_CHDR *tchdr;        /* color map info */
  2777. ULONG *map;             /* used if it's going to be remapped. */
  2778. ULONG map_flag;         /* whether or not to use remap_map info. */
  2779. ULONG imagex,imagey;    /* Size of image buffer. */
  2780. ULONG imaged;           /* Depth of Image. (IFF specific) */
  2781. ULONG *xs,*ys;          /* pos of changed area. */
  2782. ULONG *xe,*ye;          /* size of changed area. */
  2783. ULONG special;          /* Special Info. */
  2784. ULONG extra;        /* extra info needed to decode delta */
  2785. {
  2786.   LONG y,d,lines; /* ULONG min_x,max_x,min_y,max_y; */
  2787.   ULONG special_flag,r,g,b;
  2788.   UBYTE *dptr;
  2789.   XA_CHDR *chdr;
  2790.  
  2791.   if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0;
  2792.  
  2793.   special_flag = special & 0x0001;
  2794.  
  2795.   dptr = delta;
  2796.   dptr += 4;    /* skip codec size */
  2797.   d = (*dptr++) << 8;  d |= *dptr++;   /* read code either 0008 or 0000 */
  2798.   if (d == 0x0000) /* NOP */
  2799.   { /* There is one more byte 0x00 that I don't read in this case */
  2800.     *xs = *ys = *xe = *ye = 0;
  2801.     return(ACT_DLTA_NOP);
  2802.   }
  2803.   y = (*dptr++) << 8; y |= *dptr++;        /* start line */
  2804.   dptr += 2;                    /* unknown */
  2805.   lines = (*dptr++) << 8; lines |= *dptr++;    /* number of lines */
  2806.   dptr += 2;                    /* unknown */
  2807.   while(lines--)                /* loop thru lines */
  2808.   {
  2809.     ULONG d,xskip,cnt;
  2810.     xskip = *dptr++;                /* skip x pixels */
  2811.     cnt = *dptr++;                /* RLE code */
  2812.  
  2813.     if (special_flag)
  2814.     { UBYTE *iptr = (UBYTE *)(image + 3*((y * imagex) + (xskip-1)) );
  2815.       while(cnt != 0xff)                /* while not EOL */
  2816.       {
  2817.         if (cnt == 0x00) { xskip = *dptr++; iptr += 3*(xskip-1); }
  2818.         else if (cnt < 0x80)                /* run of data */
  2819.           while(cnt--) { r = *dptr++; g = *dptr++; b = *dptr++;
  2820.             *iptr++ = (UBYTE)r; *iptr++ = (UBYTE)g; 
  2821.                         *iptr++ = (UBYTE)b; }
  2822.         else                        /* repeat data */
  2823.         { cnt = 0x100 - cnt; r = *dptr++; g = *dptr++; b = *dptr++;
  2824.           while(cnt--) { *iptr++ = (UBYTE)r; *iptr++ = (UBYTE)g; 
  2825.                          *iptr++ = (UBYTE)b; }
  2826.         }
  2827.         cnt = *dptr++;                /* get new RLE code */
  2828.       } /* end of line */
  2829.     }
  2830.     else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  2831.     { UBYTE *iptr = (UBYTE *)(image + (y * imagex) + (xskip-1) );
  2832.       while(cnt != 0xff)                /* while not EOL */
  2833.       {
  2834.         if (cnt == 0x00) { xskip = *dptr++; iptr += (xskip-1); }
  2835.         else if (cnt < 0x80)                /* run of data */
  2836.           while(cnt--) { r = *dptr++; g = *dptr++; b = *dptr++;
  2837.         *iptr++ = (UBYTE)QT_Get_Color24(r,g,b,map_flag,map,chdr); }
  2838.         else                        /* repeat data */
  2839.         { cnt = 0x100 - cnt; r = *dptr++; g = *dptr++; b = *dptr++;
  2840.           d = QT_Get_Color24(r,g,b,map_flag,map,chdr);
  2841.           while(cnt--) { *iptr++ = (UBYTE)d; }
  2842.         }
  2843.         cnt = *dptr++;                /* get new RLE code */
  2844.       } /* end of line */
  2845.     }
  2846.     else if (x11_bytes_pixel==4)
  2847.     { ULONG *iptr = (ULONG *)(image + 4*((y * imagex)+(xskip-1)) );
  2848.       while(cnt != 0xff)                /* while not EOL */
  2849.       {
  2850.         if (cnt == 0x00) { xskip = *dptr++; iptr += (xskip-1); }
  2851.         else if (cnt < 0x80)                /* run of data */
  2852.           while(cnt--) { r = *dptr++; g = *dptr++; b = *dptr++;
  2853.         *iptr++ = (ULONG)QT_Get_Color24(r,g,b,map_flag,map,chdr); }
  2854.         else                        /* repeat data */
  2855.         { cnt = 0x100 - cnt; r = *dptr++; g = *dptr++; b = *dptr++;
  2856.           d = QT_Get_Color24(r,g,b,map_flag,map,chdr);
  2857.           while(cnt--) { *iptr++ = (ULONG)d; }
  2858.         }
  2859.         cnt = *dptr++;                /* get new RLE code */
  2860.       } /* end of line */
  2861.     }
  2862.     else /* if (x11_bytes_pixel==2) */
  2863.     { USHORT *iptr = (USHORT *)(image + 2*((y * imagex)+(xskip-1)) );
  2864.       while(cnt != 0xff)                /* while not EOL */
  2865.       {
  2866.         if (cnt == 0x00) { xskip = *dptr++; iptr += (xskip-1); }
  2867.         else if (cnt < 0x80)                /* run of data */
  2868.           while(cnt--) { r = *dptr++; g = *dptr++; b = *dptr++;
  2869.         *iptr++ = (USHORT)QT_Get_Color24(r,g,b,map_flag,map,chdr); }
  2870.         else                        /* repeat data */
  2871.         { cnt = 0x100 - cnt; r = *dptr++; g = *dptr++; b = *dptr++;
  2872.           d = QT_Get_Color24(r,g,b,map_flag,map,chdr);
  2873.           while(cnt--) { *iptr++ = (USHORT)d; }
  2874.         }
  2875.         cnt = *dptr++;                /* get new RLE code */
  2876.       } /* end of line */
  2877.     }
  2878.     y++;
  2879.   } /* end of lines */
  2880.  /* one more zero byte */
  2881.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  2882.  if (map_flag==TRUE) return(ACT_DLTA_MAPD);
  2883.  else return(ACT_DLTA_NORM);
  2884. }
  2885.  
  2886. typedef struct
  2887. {
  2888.   UBYTE r,g,b,pad;
  2889.   ULONG clr;
  2890.   ULONG g0,g1,g2,g3,v0,v1;
  2891. } CVID_Color;
  2892.  
  2893. #define QT_CVID_MAX_STRIPS 16
  2894. CVID_Color *qt_cvid_maps0[QT_CVID_MAX_STRIPS];
  2895. CVID_Color *qt_cvid_maps1[QT_CVID_MAX_STRIPS];
  2896. int qt_cvid_vmap0[QT_CVID_MAX_STRIPS];
  2897. int qt_cvid_vmap1[QT_CVID_MAX_STRIPS];
  2898. int qt_cvid_map_num = 0;
  2899.  
  2900.  
  2901.  
  2902. /* POD Move this internal Later */
  2903. CVID_Color *qt_cvid_cmap0,*qt_cvid_cmap1;
  2904.  
  2905. ULONG
  2906. QT_Decode_CVID(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  2907.                     xs,ys,xe,ye,special,extra)
  2908. UBYTE *image;           /* Image Buffer. */
  2909. UBYTE *delta;           /* delta data. */
  2910. ULONG dsize;            /* delta size */
  2911. XA_CHDR *tchdr;        /* color map info */
  2912. ULONG *map;             /* used if it's going to be remapped. */
  2913. ULONG map_flag;         /* whether or not to use remap_map info. */
  2914. ULONG imagex,imagey;    /* Size of image buffer. */
  2915. ULONG imaged;           /* Depth of Image. (IFF specific) */
  2916. ULONG *xs,*ys;          /* pos of changed area. */
  2917. ULONG *xe,*ye;          /* size of changed area. */
  2918. ULONG special;          /* Special Info. */
  2919. ULONG extra;        /* extra info needed to decode delta */
  2920. {
  2921.   LONG len,x,y,row_inc;
  2922.   UBYTE *dptr;
  2923.   ULONG kk,strips,cnum,xsz,ysz;
  2924.   ULONG copy_flag;
  2925.   ULONG y_top;
  2926.   XA_CHDR *chdr;
  2927.  
  2928.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  2929.   dptr = delta;
  2930.   x = y = 0;
  2931.   y_top = 0;
  2932.   row_inc = imagex - 4; if (special) row_inc *= 3;
  2933.   if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0;
  2934.  
  2935.   len = *dptr++;
  2936.   copy_flag = (len & 0x01)?(FALSE):(TRUE);
  2937.   len =(*dptr++)<<16; len |= (*dptr++)<< 8; len |= (*dptr++); /* Read Len */
  2938.   if (len != dsize) /* CHECK FOR CORRUPTION - FAIRLY COMMON */
  2939.   {
  2940.     if (len & 0x01) len++; /* AVIs tend to have a size mismatch */
  2941.     if (len != dsize)
  2942.     {
  2943.      if (xa_verbose==TRUE) 
  2944.      fprintf(stderr,"QT CVID corruption-skipping this frame %lx %lx\n",
  2945.                                 dsize,len);
  2946.      return(ACT_DLTA_NOP);
  2947.     }
  2948.   }
  2949.   xsz    = (*dptr++) << 8;  xsz    |= *dptr++;  /* xsize */
  2950.   ysz    = (*dptr++) << 8;  ysz    |= *dptr++;  /* ysize */
  2951.   strips = (*dptr++) << 8;  strips |= *dptr++;
  2952.  
  2953.   if (strips > qt_cvid_map_num)
  2954.   { int i;
  2955.     if (strips >= QT_CVID_MAX_STRIPS) 
  2956.         TheEnd1("CVID: strip ovrflow - contact Author");
  2957.     for(i=qt_cvid_map_num; i<strips; i++)
  2958.     {
  2959.       CVID_Color *cvmap;
  2960.       cvmap = (CVID_Color *)malloc( 1040 * sizeof(CVID_Color) );
  2961.       if (cvmap==0) TheEnd1("CVID: cvmap0 alloc err");
  2962.       qt_cvid_maps0[i] = cvmap;
  2963.       cvmap = (CVID_Color *)malloc( 1040 * sizeof(CVID_Color) );
  2964.       if (cvmap==0) TheEnd1("CVID: cvmap1 alloc err");
  2965.       qt_cvid_maps1[i] = cvmap;
  2966.       qt_cvid_vmap0[i] = qt_cvid_vmap1[i] = FALSE;
  2967.     }
  2968.   }
  2969.   qt_cvid_map_num = strips;
  2970.  
  2971.   DEBUG_LEVEL1 fprintf(stderr,"CVID <%lx %lx> strips %lx\n",xsz,ysz,strips);
  2972.  
  2973.   for(kk=0;kk<strips;kk++)
  2974.   {
  2975.     ULONG i,top_cid,cid,x0,y0,x1,y1; 
  2976.     LONG top_size, csize;
  2977.  
  2978. /* POD QUESTION: TREAT 20 and 22 separately or together???? */
  2979.  
  2980.     qt_cvid_cmap0 = qt_cvid_maps0[kk];
  2981.     qt_cvid_cmap1 = qt_cvid_maps1[kk];
  2982. /* OLD WAY
  2983.     if (qt_cvid_vmap0[kk]==FALSE) 
  2984.     { ULONG idx;
  2985.       CVID_Color *src,*dst;
  2986.       idx = (kk==0)?(strips-1):(kk-1);
  2987.       src = qt_cvid_maps0[idx]; dst = qt_cvid_maps0[kk];
  2988.       qt_cvid_vmap0[kk] = TRUE;
  2989.       for(i=0;i<1024;i++) dst[i]=src[i];
  2990.     }
  2991.     if (qt_cvid_vmap1[kk]==FALSE) 
  2992.     { ULONG idx;
  2993.       CVID_Color *src,*dst;
  2994.       idx = (kk==0)?(strips-1):(kk-1);
  2995.       src = qt_cvid_maps1[idx]; dst = qt_cvid_maps1[kk];
  2996.       qt_cvid_vmap1[kk] = TRUE;
  2997.       for(i=0;i<1024;i++) dst[i]=src[i];
  2998.     }
  2999. */
  3000. /* NEW WAY gardiner*/
  3001.     qt_cvid_vmap0[kk] = TRUE;
  3002.     qt_cvid_vmap1[kk] = TRUE;
  3003.     if ( kk && (copy_flag==TRUE))
  3004.     { CVID_Color *src,*dst;
  3005.       src = qt_cvid_maps0[kk-1]; dst = qt_cvid_maps0[kk];
  3006.       for(i=0;i<1024;i++) dst[i]=src[i];
  3007.       src = qt_cvid_maps1[kk-1]; dst = qt_cvid_maps1[kk];
  3008.       for(i=0;i<1024;i++) dst[i]=src[i];
  3009.     }
  3010.  
  3011.     top_cid  = (*dptr++) << 8;   top_cid  |= *dptr++;
  3012.     top_size = (*dptr++) << 8;   top_size |= *dptr++;
  3013.     y0       = (*dptr++) << 8;   y0       |= *dptr++;
  3014.     x0       = (*dptr++) << 8;   x0       |= *dptr++;
  3015.     y1       = (*dptr++) << 8;   y1       |= *dptr++;
  3016.     x1       = (*dptr++) << 8;   x1       |= *dptr++;
  3017.  
  3018.     y_top += y1;
  3019.     top_size -= 12;
  3020.     x = 0;
  3021.     if (x1 != imagex) 
  3022.     fprintf(stderr,"CVID Warning x1(%lx) != imagex(%lx)\n",x1,imagex);
  3023.     DEBUG_LEVEL2
  3024.     {
  3025.       fprintf(stderr,"   %ld) %04lx %04lx <%lx,%lx> <%lx,%lx> yt %lx\n",
  3026.         kk,top_cid,top_size,x0,y0,x1,y1,y_top);
  3027.     }
  3028.     while(top_size > 0)
  3029.     {
  3030.       cid   = (*dptr++) << 8;  cid   |= *dptr++;
  3031.       csize = (*dptr++) << 8;  csize |= *dptr++;
  3032.       /* DEBUG_LEVEL1 fprintf(stderr,"        %04lx %04lx\n",cid,csize); */
  3033.       top_size -= csize;
  3034.       csize -= 4;
  3035.       switch(cid)
  3036.       {
  3037.     case 0x2000: 
  3038.     case 0x2200: 
  3039.       { ULONG i;
  3040.         CVID_Color *cvid_map;
  3041.  
  3042.         if (cid == 0x2200)
  3043.         {
  3044.             cvid_map = qt_cvid_cmap1;
  3045.           for(i=0;i<qt_cvid_map_num;i++) qt_cvid_vmap1[i] = FALSE;
  3046.           qt_cvid_vmap1[kk] = TRUE;
  3047.         }
  3048.         else if (cid == 0x2000) 
  3049.         { 
  3050.             cvid_map = qt_cvid_cmap0;
  3051.           for(i=0;i<qt_cvid_map_num;i++) qt_cvid_vmap0[i] = FALSE;
  3052.           qt_cvid_vmap0[kk] = TRUE;
  3053.         }
  3054.  
  3055.         cnum = csize / 6;  
  3056.         for(i=0; i<cnum; i++) 
  3057.         { ULONG Y0,Y1,Y2,Y3,U,V;
  3058.           ULONG r0,r1,r2,r3,g0,g1,g2,g3,b0,b1,b2,b3;
  3059.           Y0 = (ULONG)*dptr++; Y1 = (ULONG)*dptr++;  /* luma */
  3060.           Y2 = (ULONG)*dptr++; Y3 = (ULONG)*dptr++;
  3061.           U = (ULONG)(*dptr++); /* chroma */
  3062.           V = (ULONG)(*dptr++);
  3063.  
  3064.           yuv_to_rgb(Y0,U,V,&r0,&g0,&b0);
  3065.           yuv_to_rgb(Y1,U,V,&r1,&g1,&b1);
  3066.           yuv_to_rgb(Y2,U,V,&r2,&g2,&b2);
  3067.           yuv_to_rgb(Y3,U,V,&r3,&g3,&b3);
  3068.  
  3069.           if (special)
  3070.           { register ULONG off;
  3071.             cvid_map[  i].r=r0; cvid_map[  i].g=g0; cvid_map[  i].b=b0; 
  3072.             off=i+256;
  3073.             cvid_map[off].r=r1; cvid_map[off].g=g1; cvid_map[off].b=b1;
  3074.             off+=256;
  3075.             cvid_map[off].r=r2; cvid_map[off].g=g2; cvid_map[off].b=b2;
  3076.             off+=256;
  3077.             cvid_map[off].r=r3; cvid_map[off].g=g3; cvid_map[off].b=b3;
  3078.           }
  3079.           else
  3080.           {
  3081.             cvid_map[i].clr = QT_Get_Color24(r0,g0,b0,map_flag,map,chdr);
  3082.             cvid_map[i+256].clr =QT_Get_Color24(r1,g1,b1,map_flag,map,chdr);
  3083.             cvid_map[i+512].clr =QT_Get_Color24(r2,g2,b2,map_flag,map,chdr);
  3084.             cvid_map[i+768].clr =QT_Get_Color24(r3,g3,b3,map_flag,map,chdr);
  3085.           }
  3086.         } /* end of cnum loop */
  3087.       } /* end of case */
  3088.       break;
  3089.     case 0x2100: 
  3090.     case 0x2300: 
  3091.       { ULONG k,flag,mask,ci;
  3092.         CVID_Color *cvid_map;
  3093.  
  3094.         if (cid == 0x2300) cvid_map = qt_cvid_cmap1; 
  3095.         else cvid_map = qt_cvid_cmap0;
  3096.  
  3097.         ci = 0;
  3098.         while(csize > 0)
  3099.         {
  3100.           flag  = (*dptr++) << 24;  flag |= (*dptr++) << 16;
  3101.           flag |= (*dptr++) <<  8;  flag |= *dptr++; csize -= 4;
  3102.  
  3103.           mask = 0x80000000;
  3104.           for(k=0;k<32;k++)
  3105.           {
  3106.             if (mask & flag)
  3107.         { ULONG Y0,Y1,Y2,Y3,U,V;
  3108.           ULONG r0,r1,r2,r3,g0,g1,g2,g3,b0,b1,b2,b3;
  3109.           Y0 = (ULONG)*dptr++; Y1 = (ULONG)*dptr++; /* luma */
  3110.           Y2 = (ULONG)*dptr++; Y3 = (ULONG)*dptr++;
  3111.           U = (ULONG)(*dptr++);
  3112.           V = (ULONG)(*dptr++);
  3113.           csize -= 6;
  3114.  
  3115.           yuv_to_rgb(Y0,U,V,&r0,&g0,&b0);
  3116.           yuv_to_rgb(Y1,U,V,&r1,&g1,&b1);
  3117.           yuv_to_rgb(Y2,U,V,&r2,&g2,&b2);
  3118.           yuv_to_rgb(Y3,U,V,&r3,&g3,&b3);
  3119.  
  3120.           if (special)
  3121.           { register ULONG off;
  3122.             cvid_map[ ci].r=r0; cvid_map[ ci].g=g0; cvid_map[ ci].b=b0; 
  3123.             off = ci+256;
  3124.             cvid_map[off].r=r1; cvid_map[off].g=g1; cvid_map[off].b=b1;
  3125.             off += 256;
  3126.             cvid_map[off].r=r2; cvid_map[off].g=g2; cvid_map[off].b=b2;
  3127.             off += 256;
  3128.             cvid_map[off].r=r3; cvid_map[off].g=g3; cvid_map[off].b=b3;
  3129.           }
  3130.           else
  3131.           {
  3132.             cvid_map[ci].clr = 
  3133.                 QT_Get_Color24(r0,g0,b0,map_flag,map,chdr);
  3134.             cvid_map[ci+256].clr =
  3135.                 QT_Get_Color24(r1,g1,b1,map_flag,map,chdr);
  3136.             cvid_map[ci+512].clr =
  3137.                 QT_Get_Color24(r2,g2,b2,map_flag,map,chdr);
  3138.             cvid_map[ci+768].clr =
  3139.                 QT_Get_Color24(r3,g3,b3,map_flag,map,chdr);
  3140.           }
  3141.         } /* end of if update */
  3142.             ci++; mask >>= 1;
  3143.           } /* loop thru flag */
  3144.         } /* while csize > 0 */
  3145.         if (csize != 0) fprintf(stderr,"CVID_21 err sz %04lx\n",csize);
  3146.       } /* end of case */
  3147.       break;
  3148.     case 0x3000: 
  3149.     { ULONG flag;
  3150.  
  3151.       while( (csize > 0) && (y < y_top) )
  3152.       { ULONG mask;
  3153.         LONG j;
  3154.         flag  = (*dptr++) << 24;  flag |= (*dptr++) << 16;
  3155.         flag |= (*dptr++) <<  8;  flag |= *dptr++; csize -= 4;
  3156.  
  3157.         mask = 0x80000000; j = 32;
  3158.         for(j=0; j<32; j++)
  3159.         { 
  3160.           if (y >= y_top) break;
  3161.           if (mask & flag) /* update blocks 4 bytes map 0*/
  3162.           { ULONG d0,d1,d2,d3;
  3163.             d0 = *dptr++; d1 = *dptr++; 
  3164.         d2 = *dptr++; d3 = *dptr++; csize -= 4;
  3165.         QT_CVID_C4(image,x,y,imagex,special,map_flag,
  3166.                         d0,d1,d2,d3,qt_cvid_cmap0);
  3167.           }
  3168.           else /* 1 byte map 1 */
  3169.           { ULONG d;
  3170.         d = *dptr++; csize--;
  3171.         QT_CVID_C1(image,x,y,imagex,special,map_flag,d,qt_cvid_cmap1);
  3172.           }
  3173.               x += 4; if (x >= imagex) {x = 0; y += 4;}
  3174.           mask >>= 1;
  3175.             } /* end of loop through flags */
  3176.         if (csize < 4) { dptr += csize;  csize = 0; } /* POD still ness?? */
  3177.       } /* end of csize loop */
  3178.       if (csize) dptr += csize;
  3179.     } /* end of case 3000 */
  3180.     break;
  3181.     case 0x3200: /* Every Byte is <C1> */ 
  3182.     {
  3183.       while( (csize > 0) && (y < y_top) )
  3184.       { ULONG d;
  3185.         d = *dptr++; csize--;
  3186.         QT_CVID_C1(image,x,y,imagex,special,map_flag,d,qt_cvid_cmap1);
  3187.             x += 4; if (x >= imagex) {x = 0; y += 4;}
  3188.       }
  3189.       if (csize) dptr += csize;
  3190.     } /* end of case 3200 */
  3191.     break;
  3192. /***********
  3193.  Used to have a funky combination of flags and 2 bits codes(00 01 10 11), but
  3194.  someone pointed out it was actually a combinations of 1 and 2 bit codes.
  3195.  Slightly slower this way, but easier to understand.
  3196.  
  3197.   0   SKIP
  3198.   10  C1
  3199.   11  C4
  3200.  
  3201. if(nextbit)
  3202. {
  3203.   if(nextbit)
  3204.     C4
  3205.   else
  3206.     C1
  3207. }
  3208. ***********/
  3209.     case 0x3100: 
  3210.     { ULONG mcode;
  3211.  
  3212.       while( (csize > 0) && (y < y_top) )
  3213.       { ULONG mcode,mask;
  3214.         LONG j;
  3215.         mcode  = (*dptr++) << 24;  mcode |= (*dptr++) << 16;
  3216.         mcode |= (*dptr++) <<  8;  mcode |= *dptr++; csize -= 4;
  3217.         mask = 0x80000000;
  3218.         while( (mask) && (y < y_top) )
  3219.         {
  3220.           if (mcode & mask)
  3221.           {
  3222.         if (mask == 1)
  3223.         {
  3224.           if (csize < 0) break;
  3225.           mcode  = (*dptr++) << 24;  mcode |= (*dptr++) << 16;
  3226.           mcode |= (*dptr++) <<  8;  mcode |= *dptr++; csize -= 4;
  3227.           mask = 0x80000000;
  3228.         } else mask >>= 1;
  3229.  
  3230.         if (mcode & mask)  /* C4 */
  3231.         { ULONG d0,d1,d2,d3;
  3232.           d0 = *dptr++; d1 = *dptr++;
  3233.           d2 = *dptr++; d3 = *dptr++; csize -= 4;
  3234.           QT_CVID_C4(image,x,y,imagex,special,map_flag,
  3235.                         d0,d1,d2,d3,qt_cvid_cmap0);
  3236.         }
  3237.         else /* C1 */
  3238.         { ULONG d = *dptr++; csize--;
  3239.           QT_CVID_C1(image,x,y,imagex,special,map_flag,
  3240.                             d,qt_cvid_cmap1);
  3241.         }
  3242.           } /* else SKIP */
  3243.           mask >>= 1;
  3244.           x += 4; if (x >= imagex) {x = 0; y += 4;}
  3245.         } /* end of loop through mask */
  3246.       } /* end of csize loop */
  3247.       if (csize) dptr += csize; /* better way of doing this */
  3248.     } /* end of case 3000 */
  3249.     break;
  3250.  
  3251.     default:
  3252.       fprintf(stderr,"CVID unknown cid %08lx\n",cid);
  3253.       TheEnd();
  3254.       break;
  3255.       } /* end of switch */
  3256.     } /* end of top_size */
  3257.   } /* end of strips */
  3258.   if (map_flag) return(ACT_DLTA_MAPD);
  3259.   else return(ACT_DLTA_NORM);
  3260. }
  3261.  
  3262. #define QT_CVID_C1_BLK(ip,CAST,d,cv_map,rinc) { register CAST d0,d1; \
  3263.  *ip++ = d0 = (CAST)(cv_map[d].clr); *ip++ = d0; d += 256;    \
  3264.  *ip++ = d1 = (CAST)(cv_map[d].clr); *ip   = d1; d += 256;    \
  3265.   ip += rinc; \
  3266.  *ip++ = d0; *ip++ = d0; *ip++ = d1; *ip = d1; ip += rinc;    \
  3267.  *ip++ = d0 = (CAST)(cv_map[ d ].clr); *ip++ = d0; d += 256;    \
  3268.  *ip++ = d1 = (CAST)(cv_map[ d ].clr); *ip   = d1;        \
  3269.   ip += rinc; *ip++ = d0; *ip++ = d0; *ip++ = d1; *ip = d1; }
  3270.  
  3271. #define QT_CVID_C4_BLK(ip,CAST,d0,d1,cv_map,rinc) { \
  3272.  *ip++ = (CAST)(cv_map[d0].clr); d0 += 256;  \
  3273.  *ip++ = (CAST)(cv_map[d0].clr); d0 += 256;  \
  3274.  *ip++ = (CAST)(cv_map[d1].clr); d1 += 256;  \
  3275.  *ip   = (CAST)(cv_map[d1].clr); d1 += 256; ip += rinc; \
  3276.  *ip++ = (CAST)(cv_map[d0].clr); d0 += 256;  \
  3277.  *ip++ = (CAST)(cv_map[d0].clr);           \
  3278.  *ip++ = (CAST)(cv_map[d1].clr); d1 += 256;  \
  3279.  *ip   = (CAST)(cv_map[d1].clr); }
  3280.  
  3281. void QT_CVID_C1(image,x,y,imagex,special,map_flag,d,cvid_map)
  3282. UBYTE *image;
  3283. ULONG x,y,imagex,special,map_flag,d;
  3284. CVID_Color *cvid_map;
  3285. { ULONG row_inc;
  3286.   row_inc = imagex - 3;
  3287.   if (special)
  3288.   { UBYTE *i_ptr = (UBYTE *)(image + 3*(y * imagex + x) );
  3289.     register UBYTE r0,r1,b0,b1,g0,g1;
  3290.     row_inc *= 3; row_inc -= 2;
  3291.     *i_ptr++ = r0 = (UBYTE)(cvid_map[ d ].r);  
  3292.     *i_ptr++ = g0 = (UBYTE)(cvid_map[ d ].g);  
  3293.     *i_ptr++ = b0 = (UBYTE)(cvid_map[ d ].b);  
  3294.     *i_ptr++ = r0; *i_ptr++ = g0; *i_ptr++ = b0;  d += 256;
  3295.     *i_ptr++ = r1 = (UBYTE)(cvid_map[ d ].r);  
  3296.     *i_ptr++ = g1 = (UBYTE)(cvid_map[ d ].g);  
  3297.     *i_ptr++ = b1 = (UBYTE)(cvid_map[ d ].b);  
  3298.     *i_ptr++ = r1; *i_ptr++ = g1; *i_ptr = b1;  d += 256;
  3299.      i_ptr += row_inc;
  3300.     *i_ptr++ = r0; *i_ptr++ = g0; *i_ptr++ = b0;
  3301.     *i_ptr++ = r0; *i_ptr++ = g0; *i_ptr++ = b0;
  3302.     *i_ptr++ = r1; *i_ptr++ = g1; *i_ptr++ = b1;
  3303.     *i_ptr++ = r1; *i_ptr++ = g1; *i_ptr   = b1;
  3304.      i_ptr += row_inc;
  3305.     *i_ptr++ = r0 = (UBYTE)(cvid_map[ d ].r);  
  3306.     *i_ptr++ = g0 = (UBYTE)(cvid_map[ d ].g);  
  3307.     *i_ptr++ = b0 = (UBYTE)(cvid_map[ d ].b);  
  3308.     *i_ptr++ = r0; *i_ptr++ = g0; *i_ptr++ = b0;  d += 256;
  3309.     *i_ptr++ = r1 = (UBYTE)(cvid_map[ d ].r);  
  3310.     *i_ptr++ = g1 = (UBYTE)(cvid_map[ d ].g);  
  3311.     *i_ptr++ = b1 = (UBYTE)(cvid_map[ d ].b);  
  3312.     *i_ptr++ = r1; *i_ptr++ = g1; *i_ptr = b1;
  3313.      i_ptr += row_inc;
  3314.     *i_ptr++ = r0; *i_ptr++ = g0; *i_ptr++ = b0;
  3315.     *i_ptr++ = r0; *i_ptr++ = g0; *i_ptr++ = b0;
  3316.     *i_ptr++ = r1; *i_ptr++ = g1; *i_ptr++ = b1;
  3317.     *i_ptr++ = r1; *i_ptr++ = g1; *i_ptr   = b1;
  3318.     return;
  3319.   }
  3320.   if ( (x11_bytes_pixel==1) || (map_flag == FALSE) )
  3321.   { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  3322.     QT_CVID_C1_BLK(i_ptr,UBYTE,d,cvid_map,row_inc);
  3323.   }
  3324.   else if (x11_bytes_pixel==2)
  3325.   { USHORT *i_ptr = (USHORT *)(image + ((y*imagex+x)<<1) );
  3326.     QT_CVID_C1_BLK(i_ptr,USHORT,d,cvid_map,row_inc);
  3327.   }
  3328.   else /* if (x11_bytes_pixel==4) */
  3329.   { ULONG *i_ptr = (ULONG *)(image + ((y*imagex+x)<<2) );
  3330.     QT_CVID_C1_BLK(i_ptr,ULONG,d,cvid_map,row_inc);
  3331.   }
  3332. }
  3333.  
  3334. void QT_CVID_C4(image,x,y,imagex,special,map_flag,d0,d1,d2,d3,cvid_map)
  3335. UBYTE *image;
  3336. ULONG x,y,imagex,special,map_flag;
  3337. ULONG d0,d1,d2,d3;
  3338. CVID_Color *cvid_map;
  3339. { ULONG row_inc;
  3340.   row_inc = imagex - 3;
  3341.   if (special)
  3342.   { UBYTE *i_ptr = (UBYTE *)(image + 3*(y * imagex + x) );
  3343.     row_inc *= 3; row_inc -= 2;
  3344.     *i_ptr++ = (UBYTE)(cvid_map[d0].r);  *i_ptr++ = (UBYTE)(cvid_map[d0].g);  
  3345.     *i_ptr++ = (UBYTE)(cvid_map[d0].b); d0 += 256;  
  3346.     *i_ptr++ = (UBYTE)(cvid_map[d0].r);  *i_ptr++ = (UBYTE)(cvid_map[d0].g);  
  3347.     *i_ptr++ = (UBYTE)(cvid_map[d0].b); d0 += 256;  
  3348.     *i_ptr++ = (UBYTE)(cvid_map[d1].r);  *i_ptr++ = (UBYTE)(cvid_map[d1].g);  
  3349.     *i_ptr++ = (UBYTE)(cvid_map[d1].b); d1 += 256;  
  3350.     *i_ptr++ = (UBYTE)(cvid_map[d1].r);  *i_ptr++ = (UBYTE)(cvid_map[d1].g);  
  3351.     *i_ptr   = (UBYTE)(cvid_map[d1].b); d1 += 256;  i_ptr += row_inc;
  3352.     *i_ptr++ = (UBYTE)(cvid_map[d0].r);  *i_ptr++ = (UBYTE)(cvid_map[d0].g);  
  3353.     *i_ptr++ = (UBYTE)(cvid_map[d0].b); d0 += 256;  
  3354.     *i_ptr++ = (UBYTE)(cvid_map[d0].r);  *i_ptr++ = (UBYTE)(cvid_map[d0].g);  
  3355.     *i_ptr++ = (UBYTE)(cvid_map[d0].b);
  3356.     *i_ptr++ = (UBYTE)(cvid_map[d1].r);  *i_ptr++ = (UBYTE)(cvid_map[d1].g);  
  3357.     *i_ptr++ = (UBYTE)(cvid_map[d1].b); d1 += 256;  
  3358.     *i_ptr++ = (UBYTE)(cvid_map[d1].r);  *i_ptr++ = (UBYTE)(cvid_map[d1].g);  
  3359.     *i_ptr   = (UBYTE)(cvid_map[d1].b); i_ptr += row_inc;
  3360.     *i_ptr++ = (UBYTE)(cvid_map[d2].r);  *i_ptr++ = (UBYTE)(cvid_map[d2].g);  
  3361.     *i_ptr++ = (UBYTE)(cvid_map[d2].b); d2 += 256;  
  3362.     *i_ptr++ = (UBYTE)(cvid_map[d2].r);  *i_ptr++ = (UBYTE)(cvid_map[d2].g);  
  3363.     *i_ptr++ = (UBYTE)(cvid_map[d2].b); d2 += 256;  
  3364.     *i_ptr++ = (UBYTE)(cvid_map[d3].r);  *i_ptr++ = (UBYTE)(cvid_map[d3].g);  
  3365.     *i_ptr++ = (UBYTE)(cvid_map[d3].b); d3 += 256;  
  3366.     *i_ptr++ = (UBYTE)(cvid_map[d3].r);  *i_ptr++ = (UBYTE)(cvid_map[d3].g);  
  3367.     *i_ptr   = (UBYTE)(cvid_map[d3].b); d3 += 256;  i_ptr += row_inc;
  3368.     *i_ptr++ = (UBYTE)(cvid_map[d2].r);  *i_ptr++ = (UBYTE)(cvid_map[d2].g);  
  3369.     *i_ptr++ = (UBYTE)(cvid_map[d2].b); d2 += 256;  
  3370.     *i_ptr++ = (UBYTE)(cvid_map[d2].r);  *i_ptr++ = (UBYTE)(cvid_map[d2].g);  
  3371.     *i_ptr++ = (UBYTE)(cvid_map[d2].b);
  3372.     *i_ptr++ = (UBYTE)(cvid_map[d3].r);  *i_ptr++ = (UBYTE)(cvid_map[d3].g);  
  3373.     *i_ptr++ = (UBYTE)(cvid_map[d3].b); d3 += 256;  
  3374.     *i_ptr++ = (UBYTE)(cvid_map[d3].r);  *i_ptr++ = (UBYTE)(cvid_map[d3].g);  
  3375.     *i_ptr   = (UBYTE)(cvid_map[d3].b);
  3376.     return;
  3377.   }
  3378.   if ( (x11_bytes_pixel==1) || (map_flag == FALSE) )
  3379.   { UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  3380.     QT_CVID_C4_BLK(i_ptr,UBYTE,d0,d1,cvid_map,row_inc);
  3381.     i_ptr += row_inc;
  3382.     QT_CVID_C4_BLK(i_ptr,UBYTE,d2,d3,cvid_map,row_inc);
  3383.   }
  3384.   else if (x11_bytes_pixel==2)
  3385.   { USHORT *i_ptr = (USHORT *)(image + ((y*imagex+x)<<1) );
  3386.     QT_CVID_C4_BLK(i_ptr,USHORT,d0,d1,cvid_map,row_inc);
  3387.     i_ptr += row_inc;
  3388.     QT_CVID_C4_BLK(i_ptr,USHORT,d2,d3,cvid_map,row_inc);
  3389.   }
  3390.   else /* if (x11_bytes_pixel==4) */
  3391.   { ULONG *i_ptr = (ULONG *)(image + ((y*imagex+x)<<2) );
  3392.     QT_CVID_C4_BLK(i_ptr,ULONG,d0,d1,cvid_map,row_inc);
  3393.     i_ptr += row_inc;
  3394.     QT_CVID_C4_BLK(i_ptr,ULONG,d2,d3,cvid_map,row_inc);
  3395.   }
  3396. }
  3397.  
  3398. void yuv_to_rgb(y,u,v,ir,ig,ib)
  3399. ULONG y,u,v,*ir,*ig,*ib;
  3400. {
  3401.   LONG r,g,b;
  3402.   y <<= 14;
  3403.   r = ( (LONG)(y) + QT_VR_tab[v]);
  3404.   g = ( (LONG)(y) + QT_UG_tab[u] + QT_VG_tab[v]);
  3405.   b = ( (LONG)(y) + QT_UB_tab[u]);
  3406.   if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
  3407.   r >>= 14; g >>= 14; b >>= 14;
  3408.   if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255;
  3409.   *ir = (ULONG)r; *ig = (ULONG)g; *ib = (ULONG)b;
  3410. }
  3411.   
  3412.  
  3413. /*
  3414.  *      R = Y               + 1.40200 * V
  3415.  *      G = Y - 0.34414 * U - 0.71414 * V
  3416.  *      B = Y + 1.77200 * U
  3417.  */
  3418. void QT_Gen_YUV_Tabs()
  3419. {
  3420.   LONG i;
  3421.  
  3422.   if (QT_UB_tab==0)
  3423.   {
  3424.     QT_UB_tab = (LONG *)malloc( 256 * sizeof(LONG) );
  3425.     QT_VR_tab = (LONG *)malloc( 256 * sizeof(LONG) );
  3426.     QT_UG_tab = (LONG *)malloc( 256 * sizeof(LONG) );
  3427.     QT_VG_tab = (LONG *)malloc( 256 * sizeof(LONG) );
  3428.     if (  (QT_UB_tab==0) || (QT_VR_tab==0)
  3429.     ||(QT_UG_tab==0)||(QT_VG_tab==0) ) TheEnd1("CVID: yuv tab malloc err");
  3430.   }
  3431.  
  3432.   for(i=0;i<256;i++)
  3433.   {
  3434.     float x = (float)(i);
  3435.     if (i & 0x80) x -= 256.0;
  3436.     x *= 16384.0; /* 1<<14) */
  3437.     QT_UB_tab[i] = (LONG)( 1.77200 * x);
  3438.     QT_VR_tab[i] = (LONG)( 1.40200 * x);
  3439.     QT_UG_tab[i] = (LONG)(-0.34414 * x);
  3440.     QT_VG_tab[i] = (LONG)(-0.71414 * x);
  3441.   }
  3442. }
  3443.  
  3444. char *XA_rindex(s,c)
  3445. char *s,c;
  3446. {
  3447.   int len = strlen(s);
  3448.   char *p = s + len;
  3449.   while(len >= 0)
  3450.   {
  3451.     if (*p == c) return(p);
  3452.     else {p--; len--;}
  3453.   }
  3454.   return( (char *)(NULL) );
  3455. }
  3456.  
  3457. /*********************************************
  3458.  * Read and Parse Audio Codecs
  3459.  *
  3460.  **********/
  3461. void QT_Read_Audio_STSD(fin)
  3462. { ULONG i,version,num,cur,sup;
  3463.   version = UTIL_Get_MSB_Long(fin);
  3464.   num = UTIL_Get_MSB_Long(fin);
  3465.   DEBUG_LEVEL2 fprintf(stderr,"     ver = %lx  num = %lx\n", version,num);
  3466.   if (qts_codecs == 0)
  3467.   { qts_codec_num = num;
  3468.     qts_codecs = (QTS_CODEC_HDR *)malloc(qts_codec_num * sizeof(QTS_CODEC_HDR));
  3469.     if (qts_codecs==0) TheEnd1("QT STSD: malloc err");
  3470.     cur = 0;
  3471.   }
  3472.   else
  3473.   { QTS_CODEC_HDR *tcodecs;
  3474.     tcodecs = (QTS_CODEC_HDR *)malloc((qts_codec_num+num) * sizeof(QTS_CODEC_HDR))
  3475. ;
  3476.     if (tcodecs==0) TheEnd1("QT STSD: malloc err");
  3477.     for(i=0;i<qts_codec_num;i++) tcodecs[i] = qts_codecs[i];
  3478.     cur = qts_codec_num;
  3479.     qts_codec_num += num;
  3480.     free(qts_codecs);
  3481.     qts_codecs = tcodecs;
  3482.   }
  3483.   sup = 0;
  3484.   for(i=0; i < num; i++)
  3485.   {
  3486.     sup |= QT_Read_Audio_Codec_HDR( &qts_codecs[cur], fin );
  3487.     cur++;
  3488.   }
  3489. #ifdef POD_AUDIO_BETA
  3490.   if (xa_audio_enable && sup) qt_audio_attempt = TRUE;
  3491.   else 
  3492. #endif
  3493.      qt_audio_attempt = FALSE;
  3494. }
  3495.  
  3496.  
  3497. ULONG QT_Read_Audio_Codec_HDR(c_hdr,fin)
  3498. QTS_CODEC_HDR *c_hdr;
  3499. FILE *fin;
  3500. { ULONG len;
  3501.   ULONG ret = 1;
  3502.   len            = UTIL_Get_MSB_Long(fin);
  3503.   c_hdr->compression    = UTIL_Get_MSB_Long(fin);
  3504.   c_hdr->dref_id    = UTIL_Get_MSB_Long(fin);
  3505.   c_hdr->version    = UTIL_Get_MSB_Long(fin);
  3506.   c_hdr->codec_rev    = UTIL_Get_MSB_Long(fin);
  3507.   c_hdr->vendor        = UTIL_Get_MSB_Long(fin);
  3508.   c_hdr->chan_num    = UTIL_Get_MSB_UShort(fin);
  3509.   c_hdr->bits_samp    = UTIL_Get_MSB_UShort(fin);
  3510.   c_hdr->comp_id    = UTIL_Get_MSB_UShort(fin);
  3511.   c_hdr->pack_size    = UTIL_Get_MSB_UShort(fin);
  3512.   c_hdr->samp_rate    = UTIL_Get_MSB_UShort(fin);
  3513.   c_hdr->pad        = UTIL_Get_MSB_UShort(fin);
  3514.  
  3515. #ifdef POD_AUDIO_BETA
  3516.   if (xa_verbose)
  3517.   {
  3518.     fprintf(stderr,"  Audio: "); QT_Audio_Type(c_hdr->compression);
  3519.     fprintf(stderr," Rate %ld Chans %ld Bps %ld cmp_id %lx\n",
  3520.     c_hdr->samp_rate,c_hdr->chan_num,c_hdr->bits_samp,c_hdr->comp_id);
  3521. /*PODTEMP */
  3522.     fprintf(stderr,"          v %ld crev %ld drefid %lx pk_sz %ld\n",c_hdr->version,c_hdr->codec_rev,c_hdr->dref_id,c_hdr->pack_size);
  3523.   }
  3524. #endif
  3525.  
  3526.   if (c_hdr->compression == QT_twos) c_hdr->compression =XA_AUDIO_SIGNED;
  3527.   else if (c_hdr->compression == QT_raw) c_hdr->compression =XA_AUDIO_LINEAR;
  3528.   else if (c_hdr->compression == QT_raw00) c_hdr->compression =XA_AUDIO_LINEAR;
  3529.   else
  3530.   {
  3531.     ret = 0;
  3532.     c_hdr->compression = XA_AUDIO_INVALID;
  3533.   }
  3534.   if (c_hdr->bits_samp==8) c_hdr->bps = 1;
  3535.   else if (c_hdr->bits_samp==16) c_hdr->bps = 2;
  3536.   else if (c_hdr->bits_samp==32) c_hdr->bps = 4;
  3537.   else c_hdr->bps = 100 + c_hdr->bits_samp;
  3538.  
  3539.   if (c_hdr->bps > 2) ret = 0;
  3540.   if (c_hdr->chan_num > 2) ret = 0;
  3541.  
  3542.   if (c_hdr->bps==2)        
  3543.   {
  3544.     c_hdr->compression |= XA_AUDIO_BPS_2_MSK;
  3545.     c_hdr->compression |= XA_AUDIO_BIGEND_MSK; /* only has meaning >= 2 bps */
  3546.   }
  3547.   if (c_hdr->chan_num==2)    c_hdr->compression |= XA_AUDIO_STEREO_MSK;
  3548.  
  3549.   return(ret);
  3550. }
  3551.  
  3552. void QT_Audio_Type(type)
  3553. ULONG type;
  3554. {
  3555.   switch(type)
  3556.   {
  3557.     case QT_raw:    fprintf(stderr,"PCM"); break;
  3558.     case QT_raw00:    fprintf(stderr,"PCM0"); break;
  3559.     case QT_twos:    fprintf(stderr,"TWOS"); break;
  3560.     case QT_MAC6:    fprintf(stderr,"MAC6"); break;
  3561.     default:        fprintf(stderr,"%08lx",type); break;
  3562.   }
  3563. }
  3564.  
  3565. /**************
  3566.  *
  3567.  * 
  3568.  *******/
  3569. void QT_Read_Audio_Data(fin,anim_hdr)
  3570. FILE *fin;
  3571. XA_ANIM_HDR *anim_hdr;
  3572. {
  3573.   ULONG ret,base_offset,i;
  3574.   ULONG cur_s2chunk,nxt_s2chunk;
  3575.   ULONG tag;
  3576.  
  3577. DEBUG_LEVEL1 fprintf(stderr,"QT_Read_Audio: attempt %lx co# %ld\n",
  3578.                 qt_audio_attempt,qts_chunkoff_num);
  3579.   if (qt_audio_attempt==FALSE) return;
  3580.   if (qts_samp_sizes == 0) {fprintf(stderr,"no samples\n"); return; } 
  3581.   base_offset = 0;
  3582.  
  3583.  
  3584.   cur_s2chunk = 0;
  3585.   nxt_s2chunk = qts_s2chunks[cur_s2chunk + 1].first;
  3586.   tag =  qts_s2chunks[cur_s2chunk].tag;
  3587.   qt_audio_freq  = qts_codecs[tag].samp_rate;
  3588.   qt_audio_chans = qts_codecs[tag].chan_num;
  3589.   qt_audio_bps   = qts_codecs[tag].bps;
  3590.   qt_audio_type  = qts_codecs[tag].compression;
  3591.   qt_audio_end   = 1;
  3592.  
  3593. #ifdef POD_AUDIO_BETA
  3594.   if (qts_init_duration)
  3595.   { ULONG num,snd_size,d;
  3596.     UBYTE *snd_data;
  3597.     num  = (qt_audio_freq * qts_init_duration) / qt_tk_timescale;
  3598.     snd_size = num * qt_audio_bps;
  3599.     if ((qt_audio_type & XA_AUDIO_TYPE_MASK)==XA_AUDIO_LINEAR) d = 0x80;
  3600.     else d = 0x00;
  3601.     snd_data = (UBYTE *)malloc(snd_size);
  3602.     if (snd_data==0) TheEnd1("QT aud_dat: malloc err0");
  3603.     memset((char *)(snd_data),d,snd_size); 
  3604.     XA_Add_Sound(anim_hdr,snd_data,qt_audio_type, 0, qt_audio_freq,snd_size);
  3605.   }
  3606. #endif
  3607.  
  3608.  
  3609.   /* Loop through chunk offsets */
  3610.   for(i=0; i < qts_chunkoff_num; i++)
  3611.   { UBYTE *snd_data;
  3612.     ULONG size,off,num_samps,snd_size;
  3613.     ACT_DLTA_HDR *dlta_hdr;
  3614.  
  3615.     off =  base_offset + qts_chunkoffs[i];
  3616.     fseek(fin,off,0);  /* move to start of chunk data */
  3617.  
  3618. DEBUG_LEVEL2 fprintf(stderr,"Audio: co %ld) curS2 %ld nxtS2 %ld totS2 %ld\n",
  3619.     i,cur_s2chunk,nxt_s2chunk,qts_s2chunk_num);
  3620.  
  3621.     if ( (i == nxt_s2chunk) && ((cur_s2chunk+1) < qts_s2chunk_num) )
  3622.     {
  3623.       cur_s2chunk++;
  3624.       nxt_s2chunk = qts_s2chunks[cur_s2chunk+1].first;
  3625.     }
  3626.     num_samps = qts_s2chunks[cur_s2chunk].num; /* * sttz */
  3627. DEBUG_LEVEL2 fprintf(stderr,"Audio:       curS2 %ld nxtS2 %ld num_samps %ld\n",
  3628.     cur_s2chunk,nxt_s2chunk,num_samps);
  3629.  
  3630.     /* Check tags and possibly move to new codec */
  3631.     if (qts_s2chunks[cur_s2chunk].tag >= qts_codec_num) 
  3632.     {
  3633.       fprintf(stderr,"QT Data: Warning stsc chunk invalid %ld tag %ld\n",
  3634.         cur_s2chunk,qts_s2chunks[cur_s2chunk].tag);
  3635.     } 
  3636.     else if (qts_s2chunks[cur_s2chunk].tag != tag)
  3637.     {
  3638.       tag =  qts_s2chunks[cur_s2chunk].tag;
  3639.       qt_audio_freq  = qts_codecs[tag].samp_rate;
  3640.       qt_audio_chans = qts_codecs[tag].chan_num;
  3641.       qt_audio_bps   = qts_codecs[tag].bps;
  3642.       qt_audio_type  = qts_codecs[tag].compression;
  3643.       qt_audio_end   = 1;
  3644.     }
  3645.  
  3646. /*PODNOTE: this'll only work if STSZ num is 1 or matches chunk offset size */
  3647. /* STSZ needs to same # of entries as well. */
  3648.     if (i < qts_samp_num) size = qts_samp_sizes[i];
  3649.  
  3650. #ifdef POD_AUDIO_BETA
  3651.     snd_size = num_samps * size;
  3652.     snd_data = (UBYTE *)malloc(snd_size);
  3653.     if (snd_data==0) TheEnd1("QT aud_dat: malloc err");
  3654.     ret = fread(snd_data, snd_size, 1, fin);
  3655.     if (ret != 1) { fprintf(stderr,"QT: snd rd err\n"); return; }
  3656.     XA_Add_Sound(anim_hdr,snd_data,qt_audio_type, 0, qt_audio_freq,snd_size);
  3657. #endif
  3658.   } /* end of chunk_offset loop */
  3659. }
  3660.  
  3661.  
  3662. /********
  3663.  * Have No Clue
  3664.  *
  3665.  ****/
  3666. void QT_Read_STGS(fin,len)
  3667. FILE *fin;
  3668. LONG len;
  3669. {
  3670.   ULONG i,version,num;
  3671.   ULONG samps,pad;
  3672.  
  3673.   version    = UTIL_Get_MSB_Long(fin);
  3674.   num        = UTIL_Get_MSB_Long(fin); len -= 16;
  3675.   qt_stgs_num = 0;
  3676.   for(i=0; i<num; i++)
  3677.   {
  3678.     samps    = UTIL_Get_MSB_Long(fin);
  3679.     pad        = UTIL_Get_MSB_Long(fin);    len -= 8;
  3680.     qt_stgs_num += samps;
  3681.   }
  3682.   while(len > 0) {len--; getc(fin); }
  3683. }
  3684.  
  3685.  
  3686. ULONG
  3687. QT_Decode_YUV2(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  3688.                     xs,ys,xe,ye,special,extra)
  3689. UBYTE *image;           /* Image Buffer. */
  3690. UBYTE *delta;           /* delta data. */
  3691. ULONG dsize;            /* delta size */
  3692. XA_CHDR *tchdr;        /* color map info */
  3693. ULONG *map;             /* used if it's going to be remapped. */
  3694. ULONG map_flag;         /* whether or not to use remap_map info. */
  3695. ULONG imagex,imagey;    /* Size of image buffer. */
  3696. ULONG imaged;           /* Depth of Image. (IFF specific) */
  3697. ULONG *xs,*ys;          /* pos of changed area. */
  3698. ULONG *xe,*ye;          /* size of changed area. */
  3699. ULONG special;          /* Special Info. */
  3700. ULONG extra;        /* extra info needed to decode delta */
  3701. {
  3702.   LONG size;
  3703.   UBYTE *dptr;
  3704.   UBYTE *iptr;
  3705.   XA_CHDR *chdr;
  3706.  
  3707.   dptr = delta;
  3708.  
  3709.   if (tchdr)    { chdr = (tchdr->new_chdr)?(tchdr->new_chdr):(tchdr); } 
  3710.   else        chdr=0;
  3711.   size = imagex * imagey;
  3712. /* Y0 U Y1 V  encodes two pixel Y0/U/V and Y1/U/V */
  3713.   if (special)
  3714.   { UBYTE *iptr = image;
  3715.     while(size > 0)
  3716.     { ULONG y0,y1,u,v,chroma,r,g,b;
  3717.       y0 = *dptr++; u = *dptr++;  y1 = *dptr++; v = *dptr++;  size -= 2;
  3718.       yuv_to_rgb(y0,u,v,&r,&g,&b);
  3719.       *iptr++ = r; *iptr++ = g; *iptr++ = b;
  3720.       yuv_to_rgb(y1,u,v,&r,&g,&b);
  3721.       *iptr++ = r; *iptr++ = g; *iptr++ = b;
  3722.     }
  3723.   }
  3724.   else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  3725.   { UBYTE *iptr = image;
  3726.     while(size > 0)
  3727.     { ULONG y0,y1,u,v,chroma,r,g,b;
  3728.       y0 = *dptr++; u = *dptr++;  y1 = *dptr++; v = *dptr++;  size -= 2;
  3729.       yuv_to_rgb(y0,u,v,&r,&g,&b);
  3730.       *iptr++  = (UBYTE)QT_Get_Color24(r,g,b,map_flag,map,chdr);
  3731.       yuv_to_rgb(y1,u,v,&r,&g,&b);
  3732.       *iptr++  = (UBYTE)QT_Get_Color24(r,g,b,map_flag,map,chdr);
  3733.     }
  3734.   }
  3735.   else if (x11_bytes_pixel==4)
  3736.   { ULONG *iptr = (ULONG *)image;
  3737.     while(size > 0)
  3738.     { ULONG y0,y1,u,v,chroma,r,g,b;
  3739.       y0 = *dptr++; u = *dptr++;  y1 = *dptr++; v = *dptr++;  size -= 2;
  3740.       yuv_to_rgb(y0,u,v,&r,&g,&b);
  3741.       *iptr++  = (ULONG)QT_Get_Color24(r,g,b,map_flag,map,chdr);
  3742.       yuv_to_rgb(y1,u,v,&r,&g,&b);
  3743.       *iptr++  = (ULONG)QT_Get_Color24(r,g,b,map_flag,map,chdr);
  3744.     }
  3745.   }
  3746.   else /* if (x11_bytes_pixel==2) */
  3747.   { USHORT *iptr = (USHORT *)image;
  3748.     while(size > 0)
  3749.     { ULONG y0,y1,u,v,chroma,r,g,b;
  3750.       y0 = *dptr++; u = *dptr++;  y1 = *dptr++; v = *dptr++;  size -= 2;
  3751.       yuv_to_rgb(y0,u,v,&r,&g,&b);
  3752.       *iptr++  = (USHORT)QT_Get_Color24(r,g,b,map_flag,map,chdr);
  3753.       yuv_to_rgb(y1,u,v,&r,&g,&b);
  3754.       *iptr++  = (USHORT)QT_Get_Color24(r,g,b,map_flag,map,chdr);
  3755.     }
  3756.   }
  3757.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  3758.   if (map_flag==TRUE) return(ACT_DLTA_MAPD);
  3759.   else return(ACT_DLTA_NORM);
  3760. }
  3761.  
  3762. ULONG
  3763. QT_Decode_SPIG(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  3764.                     xs,ys,xe,ye,special,extra)
  3765. UBYTE *image;           /* Image Buffer. */
  3766. UBYTE *delta;           /* delta data. */
  3767. ULONG dsize;            /* delta size */
  3768. XA_CHDR *tchdr;        /* color map info */
  3769. ULONG *map;             /* used if it's going to be remapped. */
  3770. ULONG map_flag;         /* whether or not to use remap_map info. */
  3771. ULONG imagex,imagey;    /* Size of image buffer. */
  3772. ULONG imaged;           /* Depth of Image. (IFF specific) */
  3773. ULONG *xs,*ys;          /* pos of changed area. */
  3774. ULONG *xe,*ye;          /* size of changed area. */
  3775. ULONG special;          /* Special Info. */
  3776. ULONG extra;        /* extra info needed to decode delta */
  3777. {
  3778.   LONG size,x,y,row_inc;
  3779.   UBYTE *dptr;
  3780.   UBYTE *iptr;
  3781.   XA_CHDR *chdr;
  3782.  
  3783.   dptr = delta;
  3784.  
  3785.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  3786.  return(ACT_DLTA_NOP);
  3787. }
  3788.  
  3789.  
  3790. /**************************************
  3791.  * QT_Create_Default_Cmap
  3792.  *
  3793.  * This routine recreates the Default Apple colormap.
  3794.  * It is an educated quess after looking at two quicktime animations
  3795.  * and may not be totally correct, but seems to work okay.
  3796.  */
  3797. void QT_Create_Default_Cmap(cmap)
  3798. ColorReg *cmap;
  3799. {
  3800.   static UBYTE pat[10] = {0xee,0xdd,0xbb,0xaa,0x88,0x77,0x55,0x44,0x22,0x11};
  3801.   LONG r,g,b,i;
  3802.  
  3803.   r = g = b = 0xff;
  3804.   for(i=0;i<215;i++)
  3805.   {
  3806.     cmap[i].red   = 0x101 * r;
  3807.     cmap[i].green = 0x101 * g;
  3808.     cmap[i].blue  = 0x101 * b;
  3809.     b -= 0x33;
  3810.     if (b < 0) { b = 0xff; g -= 0x33; if (g < 0) { g = 0xff; r -= 0x33; } }
  3811.   }
  3812.   for(i=0;i<10;i++)
  3813.   { ULONG d = 0x101 * pat[i];
  3814.     ULONG ip = 215 + i; 
  3815.     cmap[ip].red   = d; cmap[ip].green = cmap[ip].blue  = 0; ip += 10;
  3816.     cmap[ip].green = d; cmap[ip].red   = cmap[ip].blue  = 0; ip += 10;
  3817.     cmap[ip].blue  = d; cmap[ip].red   = cmap[ip].green = 0; ip += 10;
  3818.     cmap[ip].red   = cmap[ip].green = cmap[ip].blue  = d;
  3819.   }
  3820.   qt_cmap[255].red = qt_cmap[255].green = qt_cmap[255].blue  = 0x00;
  3821. }
  3822.    
  3823.    
  3824.  
  3825.  
  3826.  
  3827.  
  3828.  
  3829.  
  3830.